]> gitweb.factorcode.org Git - factor.git/commitdiff
base16: adding RFC 3548 version of base 16 encoding/decoding.
authorJohn Benediktsson <mrjbq7@gmail.com>
Fri, 5 Apr 2019 20:40:23 +0000 (13:40 -0700)
committerJohn Benediktsson <mrjbq7@gmail.com>
Fri, 5 Apr 2019 20:40:23 +0000 (13:40 -0700)
extra/base16/authors.txt [new file with mode: 0644]
extra/base16/base16-tests.factor [new file with mode: 0644]
extra/base16/base16.factor [new file with mode: 0644]
extra/base16/summary.txt [new file with mode: 0644]

diff --git a/extra/base16/authors.txt b/extra/base16/authors.txt
new file mode 100644 (file)
index 0000000..e091bb8
--- /dev/null
@@ -0,0 +1 @@
+John Benediktsson
diff --git a/extra/base16/base16-tests.factor b/extra/base16/base16-tests.factor
new file mode 100644 (file)
index 0000000..890fde8
--- /dev/null
@@ -0,0 +1,14 @@
+USING: base16 byte-arrays kernel sequences tools.test ;
+
+{ t } [ 256 <iota> >byte-array dup >base16 base16> = ] unit-test
+
+{ "00" } [ B{ 0 } >base16 "" like ] unit-test
+{ "01" } [ B{ 1 } >base16 "" like ] unit-test
+{ "0102" } [ B{ 1 2 } >base16 "" like ] unit-test
+
+{ B{ 0 } } [ "00" base16> ] unit-test
+{ B{ 1 } } [ "01" base16> ] unit-test
+{ B{ 1 2 } } [ "0102" base16> ] unit-test
+
+[ "0" base16> ] [ malformed-base16? ] must-fail-with
+[ "Z" base16> ] [ malformed-base16? ] must-fail-with
diff --git a/extra/base16/base16.factor b/extra/base16/base16.factor
new file mode 100644 (file)
index 0000000..2889059
--- /dev/null
@@ -0,0 +1,57 @@
+! Copyright (C) 2019 John Benediktsson.
+! See http://factorcode.org/license.txt for BSD license.
+USING: base64.private byte-arrays combinators io
+io.encodings.binary io.streams.byte-array kernel literals locals
+math namespaces sequences ;
+IN: base16
+
+ERROR: malformed-base16 ;
+
+! XXX: Optional handle lower-case input
+
+<PRIVATE
+
+<<
+CONSTANT: alphabet $[ "0123456789ABCDEF" >byte-array ]
+>>
+
+: ch>base16 ( ch -- ch )
+    alphabet nth ; inline
+
+: base16>ch ( ch -- ch )
+    $[ alphabet alphabet-inverse ] nth
+    [ malformed-base16 ] unless* ; inline
+
+:: (encode-base16) ( stream -- )
+    stream stream-read1 [
+        16 /mod [ ch>base16 write1 ] bi@
+        stream (encode-base16)
+    ] when* ;
+
+PRIVATE>
+
+: encode-base16 ( -- )
+    input-stream get (encode-base16) ;
+
+<PRIVATE
+
+: decode2 ( seq -- n )
+    first2 [ base16>ch ] bi@ [ 16 * ] [ + ] bi* ;
+
+:: (decode-base16) ( stream -- )
+    2 stream stream-read dup length {
+        { 0 [ drop ] }
+        { 2 [ decode2 write1 stream (decode-base16) ] }
+        [ malformed-base16 ]
+    } case ;
+
+PRIVATE>
+
+: decode-base16 ( -- )
+    input-stream get (decode-base16) ;
+
+: >base16 ( seq -- base16 )
+    binary [ binary [ encode-base16 ] with-byte-reader ] with-byte-writer ;
+
+: base16> ( base16 -- seq )
+    binary [ binary [ decode-base16 ] with-byte-reader ] with-byte-writer ;
diff --git a/extra/base16/summary.txt b/extra/base16/summary.txt
new file mode 100644 (file)
index 0000000..bd04219
--- /dev/null
@@ -0,0 +1 @@
+Base 16 encoding/decoding (RFC 3548)