Skip to content

Commit

Permalink
base32: adding zbase32, the "human-oriented" Base32
Browse files Browse the repository at this point in the history
  • Loading branch information
mrjbq7 committed Dec 8, 2024
1 parent 7e8c2f9 commit 53d7e6d
Show file tree
Hide file tree
Showing 3 changed files with 97 additions and 0 deletions.
14 changes: 14 additions & 0 deletions basis/base32/base32-docs.factor
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,15 @@ HELP: >base32-crockford
{ $values { "n" integer } { "base32" sequence } }
{ $description "Encode from Douglas Crockford's Base32 encoding." } ;

HELP: >zbase32
{ $values { "seq" sequence } { "zbase32" sequence } }
{ $description "Encode into the \"human-oriented\" Base32 encoding." } ;

HELP: zbase32>
{ $values { "zbase32" sequence } { "seq" sequence } }
{ $description "Decode from the \"human-oriented\" Base32 encoding." } ;


ARTICLE: "base32" "Base32 conversions"
"The " { $vocab-link "base32" } " vocabulary supports encoding and decoding of various Base32 encoding formats, including:"
$nl
Expand All @@ -45,6 +54,11 @@ $nl
base32-crockford>
>base32-crockford-checksum
base32-crockford-checksum>
}
"Human-oriented Base32 encoding:"
{ $subsections
>zbase32
zbase32>
} ;

ABOUT: "base32"
16 changes: 16 additions & 0 deletions basis/base32/base32-tests.factor
Original file line number Diff line number Diff line change
Expand Up @@ -90,3 +90,19 @@ USING: base32 byte-arrays kernel sequences strings tools.test ;
{ 1234 } [ "i6JD" base32-crockford-checksum> ] unit-test
{ 0 } [ "0" base32-crockford> ] unit-test
{ 0 } [ "00" base32-crockford-checksum> ] unit-test

{ "" } [ "" >zbase32 >string ] unit-test
{ "ca======" } [ "f" >zbase32 >string ] unit-test
{ "c3zo====" } [ "fo" >zbase32 >string ] unit-test
{ "c3zs6===" } [ "foo" >zbase32 >string ] unit-test
{ "c3zs6ao=" } [ "foob" >zbase32 >string ] unit-test
{ "c3zs6aub" } [ "fooba" >zbase32 >string ] unit-test
{ "c3zs6aubqe======" } [ "foobar" >zbase32 >string ] unit-test

{ "" } [ "" zbase32> >string ] unit-test
{ "f" } [ "ca======" zbase32> >string ] unit-test
{ "fo" } [ "c3zo====" zbase32> >string ] unit-test
{ "foo" } [ "c3zs6===" zbase32> >string ] unit-test
{ "foob" } [ "c3zs6ao=" zbase32> >string ] unit-test
{ "fooba" } [ "c3zs6aub" zbase32> >string ] unit-test
{ "foobar" } [ "c3zs6aubqe======" zbase32> >string ] unit-test
67 changes: 67 additions & 0 deletions basis/base32/base32.factor
Original file line number Diff line number Diff line change
Expand Up @@ -185,3 +185,70 @@ PRIVATE>

: >base32-crockford-checksum ( n -- base32 )
[ >base32-crockford ] keep 37 mod base32-crockford-checksum nth suffix ;

ERROR: malformed-zbase32 ;

<PRIVATE

<<
CONSTANT: zbase32-alphabet $[ "ybndrfg8ejkmcpqxot1uwisza345h769" >byte-array ]
>>

: ch>zbase32 ( ch -- ch )
zbase32-alphabet nth ; inline

: zbase32>ch ( ch -- ch )
$[ zbase32-alphabet alphabet-inverse 0 CHAR: = pick set-nth ] nth
[ malformed-zbase32 ] unless* { fixnum } declare ; inline

: zencode5 ( seq -- byte-array )
be> { -35 -30 -25 -20 -15 -10 -5 0 } '[
shift 0x1f bitand ch>zbase32
] with B{ } map-as ; inline

: zencode-pad ( seq n -- byte-array )
[ 5 0 pad-tail zencode5 ] [ B{ 0 2 4 5 7 } nth ] bi* head-slice
8 CHAR: = pad-tail ; inline

: (encode-zbase32) ( stream column -- )
5 pick stream-read dup length {
{ 0 [ 3drop ] }
{ 5 [ zencode5 write-lines (encode-zbase32) ] }
[ zencode-pad write-lines (encode-zbase32) ]
} case ;

PRIVATE>

: encode-zbase32 ( -- )
input-stream get f (encode-zbase32) ;

: encode-zbase32-lines ( -- )
input-stream get 0 (encode-zbase32) ;

<PRIVATE

: zdecode8 ( seq -- )
[ 0 [ zbase32>ch swap 5 shift bitor ] reduce 5 >be ]
[ [ CHAR: = = ] count ] bi
[ write ] [ B{ 0 4 0 3 2 0 1 } nth head-slice write ] if-zero ; inline

: (decode-zbase32) ( stream -- )
8 "\n\r" pick read-ignoring dup length {
{ 0 [ 2drop ] }
{ 8 [ zdecode8 (decode-zbase32) ] }
[ drop 8 CHAR: = pad-tail zdecode8 (decode-zbase32) ]
} case ;

PRIVATE>

: decode-zbase32 ( -- )
input-stream get (decode-zbase32) ;

: >zbase32 ( seq -- zbase32 )
binary [ binary [ encode-zbase32 ] with-byte-reader ] with-byte-writer ;

: zbase32> ( zbase32 -- seq )
binary [ binary [ decode-zbase32 ] with-byte-reader ] with-byte-writer ;

: >zbase32-lines ( seq -- zbase32 )
binary [ binary [ encode-zbase32-lines ] with-byte-reader ] with-byte-writer ;

0 comments on commit 53d7e6d

Please sign in to comment.