]> gitweb.factorcode.org Git - factor.git/commitdiff
base36: adding base36 encoder/decoder.
authorJohn Benediktsson <mrjbq7@gmail.com>
Sun, 13 Dec 2020 18:32:13 +0000 (10:32 -0800)
committerJohn Benediktsson <mrjbq7@gmail.com>
Sun, 13 Dec 2020 18:32:13 +0000 (10:32 -0800)
extra/base36/authors.txt [new file with mode: 0644]
extra/base36/base36-tests.factor [new file with mode: 0644]
extra/base36/base36.factor [new file with mode: 0644]
extra/base36/summary.txt [new file with mode: 0644]

diff --git a/extra/base36/authors.txt b/extra/base36/authors.txt
new file mode 100644 (file)
index 0000000..e091bb8
--- /dev/null
@@ -0,0 +1 @@
+John Benediktsson
diff --git a/extra/base36/base36-tests.factor b/extra/base36/base36-tests.factor
new file mode 100644 (file)
index 0000000..fc6c1c2
--- /dev/null
@@ -0,0 +1,16 @@
+USING: base36 math.parser strings tools.test ;
+
+{ "" } [ "" >base36 >string ] unit-test
+{ "" } [ "" base36> >string ] unit-test
+
+{ "0" } [ B{ 0 } >base36 >string ] unit-test
+{ B{ 0 } } [ "0" base36> ] unit-test
+
+{ "00" } [ B{ 0 0 } >base36 >string ] unit-test
+{ B{ 0 0 } } [ "00" base36> ] unit-test
+
+{ "ZIK0ZJ" } [ 2147483647 n>base36 >string ] unit-test
+{ 2147483647 } [ "ZIK0ZJ" base36>n ] unit-test
+
+{ "1Y2P0IJ32E8E7" } [ 9223372036854775807 n>base36 >string ] unit-test
+{ 9223372036854775807 } [ "1Y2P0IJ32E8E7" base36>n ] unit-test
diff --git a/extra/base36/base36.factor b/extra/base36/base36.factor
new file mode 100644 (file)
index 0000000..e937e05
--- /dev/null
@@ -0,0 +1,51 @@
+! Copyright (C) 2020 John Benediktsson.
+! See http://factorcode.org/license.txt for BSD license.
+
+USING: base64.private byte-arrays checksums checksums.sha
+io.binary kernel kernel.private literals math math.functions
+sequences ;
+
+IN: base36
+
+ERROR: malformed-base36 ;
+
+<PRIVATE
+
+<<
+CONSTANT: alphabet $[
+    "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"
+    >byte-array
+]
+>>
+
+PRIVATE>
+
+: ch>base36 ( ch -- ch )
+    alphabet nth ; inline
+
+: base36>ch ( ch -- ch )
+    $[ alphabet alphabet-inverse ] nth
+    [ malformed-base36 ] unless* { fixnum } declare ; inline
+
+:: >base36 ( seq -- base36 )
+    BV{ } clone :> accum
+    seq [ zero? not ] find [ drop seq length ] unless :> i
+    seq i tail-slice be>
+    [ 36 /mod ch>base36 accum push ] until-zero
+    i alphabet first '[ _ accum push ] times
+    accum reverse! B{ } like ;
+
+:: base36> ( base36 -- seq )
+    BV{ } clone :> accum
+    base36 alphabet first '[ _ = not ] find
+    [ drop base36 length ] unless :> i
+    0 base36 [ [ 36 * ] dip base36>ch + ] i each-from
+    [ 256 /mod accum push ] until-zero
+    i [ 0 accum push ] times
+    accum reverse! B{ } like ;
+
+: n>base36 ( n -- base36 )
+    dup log2 1 + 8 / ceiling >integer >be >base36 ;
+
+: base36>n ( base36 -- n )
+    base36> be> ;
diff --git a/extra/base36/summary.txt b/extra/base36/summary.txt
new file mode 100644 (file)
index 0000000..5397e8a
--- /dev/null
@@ -0,0 +1 @@
+Base36 encoding/decoding