diff --git a/morphisms/Makefile b/morphisms/Makefile
index 4eb2d4d..2394a86 100644
--- a/morphisms/Makefile
+++ b/morphisms/Makefile
@@ -1,9 +1,13 @@
-TARGETS=lib/posint.so
+LIB_DIR=$(shell pwd)/lib
+TARGETS=lib/libmorph_length_prefix.so lib/libmorph_posint.so test
 
 all: $(TARGETS)
 
-lib/%.so: src/%.c
-	gcc -shared -o $@ -fPIC $<
+lib/libmorph_%.so: src/%.c
+	$(CC) -O3 -shared -o $@ -fPIC -Iinclude $<
+
+test: test.c lib/libmorph_length_prefix.so lib/libmorph_posint.so
+	$(CC) -O3 -L$(LIB_DIR) -o $@ -Iinclude $< -llength_prefix -lposint
 
 clean:
 	rm $(TARGETS)
diff --git a/morphisms/include/morphisms/length_prefix.h b/morphisms/include/morphisms/length_prefix.h
new file mode 100644
index 0000000..1ce7346
--- /dev/null
+++ b/morphisms/include/morphisms/length_prefix.h
@@ -0,0 +1,61 @@
+#pragma once
+#include <stdint.h>
+
+/* UInt8 */
+
+struct LengthPrefixUInt8Array {
+    uint64_t len;
+    uint8_t items[];
+};
+
+void length_prefix_uint8_array_clear(
+    struct LengthPrefixUInt8Array * data
+);
+void length_prefix_uint8_array_push(
+    struct LengthPrefixUInt8Array * data,
+    uint8_t value
+);
+int length_prefix_uint8_array_reverse(
+    struct LengthPrefixUInt8Array const * restrict src,
+    struct LengthPrefixUInt8Array * restrict dst
+);
+void length_prefix_uint8_array_dump(
+    struct LengthPrefixUInt8Array const * data
+);
+
+
+/* UInt64 */
+
+struct LengthPrefixUInt64Array {
+    uint64_t len;
+    uint64_t items[];
+};
+
+void length_prefix_uint64_array_clear(
+    struct LengthPrefixUInt64Array * data
+);
+void length_prefix_uint64_array_push(
+    struct LengthPrefixUInt64Array * data,
+    uint64_t value
+);
+int length_prefix_uint64_array_reverse(
+    struct LengthPrefixUInt64Array const * restrict src,
+    struct LengthPrefixUInt64Array * restrict dst
+);
+void length_prefix_uint64_array_dump(
+    struct LengthPrefixUInt64Array const * data
+);
+
+
+/*
+ * Morphisms
+ */
+
+int morph_string_as_nullterm_to_length_prefix(
+    char const * restrict src,
+    struct LengthPrefixUInt8Array * restrict dst
+);
+int morph_string_as_length_prefix_to_nullterm(
+    struct LengthPrefixUInt8Array const * restrict src,
+    char * restrict dst
+);
diff --git a/morphisms/include/morphisms/posint.h b/morphisms/include/morphisms/posint.h
new file mode 100644
index 0000000..08568a6
--- /dev/null
+++ b/morphisms/include/morphisms/posint.h
@@ -0,0 +1,34 @@
+#pragma once
+#include <stdint.h>
+#include <morphisms/length_prefix.h>
+
+int morph_digit_as_char_to_uint8(
+    char const * restrict src,
+    uint8_t * restrict dst
+);
+int morph_digit_as_char_to_uint64(
+    char const * restrict src,
+    uint64_t * restrict dst
+);
+int morph_digit_as_uint8_to_char(
+    uint8_t const * restrict src,
+    char * restrict dst
+);
+int morph_digit_as_uint64_to_char(
+    uint64_t const * restrict src,
+    char * restrict dst
+);
+
+int morph_posint_endianness(
+    uint64_t const radix,
+
+    struct LengthPrefixUInt64Array const * restrict src,
+    struct LengthPrefixUInt64Array * restrict dst
+);
+int morph_posint_radix(
+    uint64_t const src_radix,
+    uint64_t const dst_radix,
+
+    struct LengthPrefixUInt64Array const * restrict src,
+    struct LengthPrefixUInt64Array * restrict dst
+);
diff --git a/morphisms/length_prefix.morphism-base b/morphisms/length_prefix.morphism-base
new file mode 100644
index 0000000..7a74e26
--- /dev/null
+++ b/morphisms/length_prefix.morphism-base
@@ -0,0 +1,9 @@
+morph_string_as_nullterm_to_length_prefix ()
+    [~<ValueDelim '\0'> Char ~ Ascii]
+--> [~<LengthPrefix x86.UInt64> Char ~ Ascii]
+@lib/array.so:src/array.c
+
+morph_string_as_length_prefix_to_nullterm ()
+    [~<LengthPrefix x86.UInt64> Char ~ Ascii]
+--> [~<ValueDelim '\0'> Char ~ Ascii]
+@lib/array.so:src/array.c
diff --git a/morphisms/src/length_prefix.c b/morphisms/src/length_prefix.c
new file mode 100644
index 0000000..cd29532
--- /dev/null
+++ b/morphisms/src/length_prefix.c
@@ -0,0 +1,102 @@
+#include <stdio.h>
+#include <stdint.h>
+
+#include <morphisms/length_prefix.h>
+
+void length_prefix_uint64_array_clear(
+    struct LengthPrefixUInt64Array * data
+) {
+    data->len = 0;
+}
+
+void length_prefix_uint64_array_push(
+    struct LengthPrefixUInt64Array * data,
+    uint64_t value
+) {
+    data->items[ data->len ] = value;
+    data->len += 1;
+}
+
+int length_prefix_uint64_array_reverse(
+    struct LengthPrefixUInt64Array const * restrict src,
+    struct LengthPrefixUInt64Array * restrict dst
+) {
+    dst->len = src->len;
+    for(uint64_t i = 0; i < src->len; ++i) {
+        dst->items[i] = src->items[src->len - i - 1];
+    }
+    return 0;
+}
+
+void length_prefix_uint64_array_dump(
+    struct LengthPrefixUInt64Array const * data
+) {
+    printf("Len = %d, [", data->len);
+    for( uint64_t i = 0; i < data->len; ++i ) {
+        printf("%d; ", data->items[i]);
+    }
+    printf("]\n");
+}
+
+
+
+
+void length_prefix_uint8_array_clear(
+    struct LengthPrefixUInt8Array * data
+) {
+    data->len = 0;
+}
+
+void length_prefix_uint8_array_push(
+    struct LengthPrefixUInt8Array * data,
+    uint8_t value
+) {
+    data->items[ data->len ] = value;
+    data->len += 1;
+}
+
+int length_prefix_uint8_array_reverse(
+    struct LengthPrefixUInt8Array const * restrict src,
+    struct LengthPrefixUInt8Array * restrict dst
+) {
+    dst->len = src->len;
+    for(uint64_t i = 0; i < src->len; ++i) {
+        dst->items[i] = src->items[src->len - i - 1];
+    }
+    return 0;
+}
+
+void length_prefix_uint8_array_dump(
+    struct LengthPrefixUInt8Array const * data
+) {
+    printf("Len = %d, [", data->len);
+    for( uint64_t i = 0; i < data->len; ++i ) {
+        printf("%d; ", data->items[i]);
+    }
+    printf("]\n");
+}
+
+int morph_string_as_nullterm_to_length_prefix(
+    char const * restrict src,
+    struct LengthPrefixUInt8Array * restrict dst
+) {
+    length_prefix_uint8_array_clear(dst);
+    while( *src ) {
+        length_prefix_uint8_array_push(dst, *src);
+        src++;
+    }
+
+    return 0;
+}
+
+int morph_string_as_length_prefix_to_nullterm(
+    struct LengthPrefixUInt8Array const * restrict src,
+    char * restrict dst
+) {
+    for( uint64_t i = 0; i < src->len; ++i ) {
+        *dst ++ = src->items[i];
+    }
+    *dst = '\0';
+
+    return 0;
+}
diff --git a/morphisms/src/length_prefix_array.c b/morphisms/src/length_prefix_array.c
deleted file mode 100644
index 4f908e6..0000000
--- a/morphisms/src/length_prefix_array.c
+++ /dev/null
@@ -1,42 +0,0 @@
-#include <stdio.h>
-#include <stdint.h>
-
-struct LengthPrefixUInt64Array {
-    uint64_t len;
-    uint64_t items[];
-};
-
-void length_prefix_uint64_array_clear(
-    struct LengthPrefixUInt64Array * data
-) {
-    data->len = 0;
-}
-
-void length_prefix_uint64_array_push(
-    struct LengthPrefixUInt64Array * data,
-    uint64_t value
-) {
-    data->items[ data->len ] = value;
-    data->len += 1;
-}
-
-int length_prefix_uint64_array_reverse(
-    struct LengthPrefixUInt64Array const * restrict src,
-    struct LengthPrefixUInt64Array * restrict dst
-) {
-    dst->len = src->len;
-    for(uint64_t i = 0; i < src->len; ++i) {
-        dst->items[i] = src->items[src->len - i - 1];
-    }
-    return 0;
-}
-
-void length_prefix_uint64_array_dump(
-    struct LengthPrefixUInt64Array const * data
-) {
-    printf("Len = %d, [", data->len);
-    for( uint64_t i = 0; i < data->len; ++i ) {
-        printf("%d; ", data->items[i]);
-    }
-    printf("]\n");
-}
diff --git a/morphisms/src/posint.c b/morphisms/src/posint.c
index 5d25f20..cc35955 100644
--- a/morphisms/src/posint.c
+++ b/morphisms/src/posint.c
@@ -1,5 +1,5 @@
 #include <stdint.h>
-#include "length_prefix_array.c"
+#include <morphisms/length_prefix.h>
 
 int morph_digit_as_char_to_uint8(
     char const * restrict src,
@@ -47,6 +47,20 @@ int morph_digit_as_uint8_to_char(
     return 0;
 }
 
+int morph_digit_as_uint64_to_char(
+    uint64_t const * restrict src,
+    char * restrict dst
+) {
+    if ( *src < 10 )
+        *dst = *src + '0';
+    else if( *dst < 16 )
+        *dst = *src - 0xa + 'a';
+    else
+        return -1;
+
+    return 0;
+}
+
 /* switches endianness by reversing the digit sequence
  */
 int morph_posint_endianness(
diff --git a/morphisms/test.c b/morphisms/test.c
new file mode 100644
index 0000000..8fe26b7
--- /dev/null
+++ b/morphisms/test.c
@@ -0,0 +1,60 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <morphisms/length_prefix.h>
+#include <morphisms/posint.h>
+
+int main( int argc, char * argv[] ) {
+    char * int1 = malloc(4096);
+    struct LengthPrefixUInt8Array * int2 = malloc(4096);
+    struct LengthPrefixUInt64Array * int3 = malloc(4096);
+    struct LengthPrefixUInt64Array * int4 = malloc(4096);
+    struct LengthPrefixUInt64Array * int5 = malloc(4096);
+    struct LengthPrefixUInt64Array * int6 = malloc(4096);
+    struct LengthPrefixUInt8Array * int7 = malloc(4096);
+    char * int8 = malloc(4096);
+
+    // ℕ ~ <PosInt 10 BigEndian> ~ [~<ValueDelim '\0'> <Digit 10> ~ Char ~ Ascii]
+    scanf("%s", int1);
+
+    // morph to
+    //     ℕ ~ <PosInt 10 BigEndian> ~ [~<LengthPrefix x86.UInt64> <Digit 10> ~ Char ~ Ascii]
+    morph_string_as_nullterm_to_length_prefix( int1, int2 );
+
+    // morph to
+    //     ℕ ~ <PosInt 10 BigEndian> ~ [~<LengthPrefix x86.UInt64> <Digit 10> ~ ℤ_10 ~ x86.UInt64]
+    int3->len = int2->len;
+    for( uint64_t i = 0; i < int2->len; ++i )
+        morph_digit_as_char_to_uint64( &int2->items[i], &int3->items[i] );
+
+    // morph to
+    //    ℕ ~ <PosInt 10 LittleEndian> ~ [~<LengthPrefix x86.UInt64> <Digit 10> ~ ℤ_10 ~ x86.UInt64]
+    morph_posint_endianness( 10, int3, int4 );
+
+    // morph to
+    //    ℕ ~ <PosInt 16 LittleEndian> ~ [~<LengthPrefix x86.UInt64> <Digit 16> ~ ℤ_16 ~ x86.UInt64]
+    morph_posint_radix(
+        10,
+        16,
+        int4,
+        int5
+    );
+
+    // morph to
+    //    ℕ ~ <PosInt 16 BigEndian> ~ [~<LengthPrefix x86.UInt64> <Digit 16> ~ ℤ_16 ~ x86.UInt64]
+    morph_posint_endianness( 10, int5, int6 );
+
+    // morph to
+    //    ℕ ~ <PosInt 16 BigEndian> ~ [~<LengthPrefix x86.UInt64> <Digit 16> ~ Char ~ Ascii]
+    int7->len = int6->len;
+    for( uint64_t i = 0; i < int6->len; ++i )
+        morph_digit_as_uint64_to_char( &int6->items[i], &int7->items[i] );
+
+    // morph to
+    //    ℕ ~ <PosInt 16 BigEndian> ~ [~<ValueDelim '\0'> <Digit 16> ~ Char ~ Ascii]
+    morph_string_as_length_prefix_to_nullterm( int7, int8 );
+
+    printf("%s\n", int8);
+
+    return 0;
+}