zuse: moves lib/base64

This commit is contained in:
Joe Bryan 2020-12-08 02:36:11 -08:00
parent f9640f96ab
commit fd707761f8
9 changed files with 224 additions and 258 deletions

View File

@ -1,5 +1,5 @@
/- asn1
/+ base64, der, primitive-rsa, *pkcs, *jose, default-agent, verb
/+ der, primitive-rsa, *pkcs, *jose, default-agent, verb
=, eyre
=* rsa primitive-rsa
::
@ -7,11 +7,11 @@
:: +en-base64url: url-safe base64 encoding, without padding
::
++ en-base64url
~(en base64 | &)
~(en base64:mimes:html | &)
:: +de-base64url: url-safe base64 decoding, without padding
::
++ de-base64url
~(de base64 | &)
~(de base64:mimes:html | &)
:: +join-turf
::
++ join-turf

View File

@ -1,5 +1,5 @@
/- lens, *sole
/+ base64, *server, default-agent
/+ *server, default-agent
/= lens-mark /mar/lens/command :: TODO: ask clay to build a $tube
=, format
|%
@ -83,7 +83,7 @@
[%pass /export %agent [our.bowl app.source.com] %watch /export]~
::
%import
?~ enc=(de:base64 base64-jam.source.com)
?~ enc=(de:base64:mimes:html base64-jam.source.com)
!!
::
=/ c=* (cue q.u.enc)
@ -96,7 +96,7 @@
=/ jon
=/ =atom (jam (export-all our.bowl now.bowl))
=/ =octs [(met 3 atom) atom]
=/ enc (en:base64 octs)
=/ enc (en:base64:mimes:html octs)
(pairs:enjs:format file+s+output data+s+enc ~)
:_ this
%+ give-simple-payload:app eyre-id
@ -104,7 +104,7 @@
::
%import-all
~& %import-all
=/ enc (de:base64 base64-jam.source.com)
=/ enc (de:base64:mimes:html base64-jam.source.com)
?~ enc !!
=/ by-app ;;((list [@tas *]) (cue q.u.enc))
:_ this
@ -192,7 +192,7 @@
=/ jon=json
=/ =atom (jam data)
=/ =octs [(met 3 atom) atom]
=/ enc (en:base64 octs)
=/ enc (en:base64:mimes:html octs)
(pairs:enjs:format file+s+output data+s+enc ~)
::
:_ this
@ -222,13 +222,11 @@
[%mime p.fec (as-octs:mimes:html (jam q.fec))]
::
%sav
:: XX use +en:base64 or produce %mime a la %sag
::
%- some
:- %json
%- pairs:enjs:format
:~ file+s+(crip <`path`p.fec>)
data+s+(crip (en-base64:mimes:html q.fec))
data+s+(en:base64:mimes:html (met 3 q.fec) q.fec)
==
::
%mor

View File

@ -1,133 +0,0 @@
:: |base64: flexible base64 encoding for little-endian atoms
::
:: pad: include padding when encoding, require when decoding
:: url: use url-safe characters '-' for '+' and '_' for '/'
::
::
=+ [pad=& url=|]
|%
::
+$ byte @D
+$ word24 @
::
++ div-ceil
:: divide, rounding up.
|= [x=@ y=@] ^- @
?: =(0 (mod x y))
(div x y)
+((div x y))
::
++ explode-bytes
:: Explode a bytestring into list of bytes. Result is in LSB order.
|= =octs ^- (list byte)
=/ atom-byte-width (met 3 q.octs)
=/ leading-zeros (sub p.octs atom-byte-width)
(weld (reap leading-zeros 0) (rip 3 q.octs))
::
++ explode-words
:: Explode a bytestring to words of bit-width `wid`. Result is in LSW order.
|= [wid=@ =octs]
^- (list @)
=/ atom-bit-width (met 0 q.octs)
=/ octs-bit-width (mul 8 p.octs)
=/ atom-word-width (div-ceil atom-bit-width wid)
=/ rslt-word-width (div-ceil octs-bit-width wid)
=/ pad (sub rslt-word-width atom-word-width)
=/ x (rip [0 wid] q.octs)
%+ weld x
(reap pad 0)
::
:: +en:base64: encode +octs to base64 cord
::
:: Encode an `octs` into a base64 string.
::
:: First, we break up the input into a list of 24-bit words. The input
:: might not be a multiple of 24-bits, so we add 0-2 padding bytes at
:: the end (to the least-significant side, with a left-shift).
::
:: Then, we encode each block into four base64 characters.
::
:: Finally we remove the padding that we added at the beginning: for
:: each byte that was added, we replace one character with an = (unless
:: `pad` is false, in which case we just remove the extra characters).
::
++ en
^- $-(octs cord)
::
=/ cha
?: url
'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_'
'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'
::
|^ |= bs=octs ^- cord
=/ [padding=@ blocks=(list word24)]
(octs-to-blocks bs)
(crip (flop (unpad padding (encode-blocks blocks))))
::
++ octs-to-blocks
|= bs=octs ^- [padding=@ud (list word24)]
=/ padding=@ud (~(dif fo 3) 0 p.bs)
=/ padded=octs [(add padding p.bs) (lsh [3 padding] (rev 3 bs))]
[padding (explode-words 24 padded)]
::
++ unpad
|= [extra=@ t=tape] ^- tape
=/ without (slag extra t)
?. pad without
(weld (reap extra '=') without)
::
++ encode-blocks
|= ws=(list word24) ^- tape
(zing (turn ws encode-block))
::
++ encode-block
|= w=word24 ^- tape
=/ a (cut 3 [(cut 0 [0 6] w) 1] cha)
=/ b (cut 3 [(cut 0 [6 6] w) 1] cha)
=/ c (cut 3 [(cut 0 [12 6] w) 1] cha)
=/ d (cut 3 [(cut 0 [18 6] w) 1] cha)
~[a b c d]
--
::
:: +de:base64: decode base64 cord to (unit @)
::
++ de
|= a=cord
^- (unit octs)
(rush a parse)
:: +parse:base64: parse base64 cord to +octs
::
++ parse
=< ^- $-(nail (like octs))
%+ sear reduce
;~ plug
%- plus ;~ pose
(cook |=(a=@ (sub a 'A')) (shim 'A' 'Z'))
(cook |=(a=@ (sub a 'G')) (shim 'a' 'z'))
(cook |=(a=@ (add a 4)) (shim '0' '9'))
(cold 62 (just ?:(url '-' '+')))
(cold 63 (just ?:(url '_' '/')))
==
(stun 0^2 (cold %0 tis))
==
|%
:: +reduce:parse:base64: reduce, measure, and swap base64 digits
::
++ reduce
|= [dat=(list @) dap=(list @)]
^- (unit octs)
=/ lat (lent dat)
=/ lap (lent dap)
=/ dif (~(dif fo 4) 0 lat)
?: &(pad !=(dif lap))
:: padding required and incorrect
~&(%base-64-padding-err-one ~)
?: &(!pad !=(0 lap))
:: padding not required but present
~&(%base-64-padding-err-two ~)
=/ len (sub (mul 3 (div (add lat dif) 4)) dif)
:+ ~ len
%+ swp 3
(rep [0 6] (flop (weld dat (reap dif 0))))
--
--

View File

@ -1,5 +1,5 @@
/- *contact-view, *contact-hook
/+ base64, group-store, resource
/+ group-store, resource
|%
++ nu :: parse number as hex
|= jon=json
@ -222,7 +222,7 @@
?- -.avatar
%url avatar
%octt
=. octs.avatar (need (de:base64 q.octs.avatar))
=. octs.avatar (need (de:base64:mimes:html q.octs.avatar))
avatar
==
::

View File

@ -1,14 +1,14 @@
/+ base64, primitive-rsa, *pkcs
/+ primitive-rsa, *pkcs
=* rsa primitive-rsa
|%
:: +en-base64url: url-safe base64 encoding, without padding
::
++ en-base64url
~(en base64 | &)
~(en base64:mimes:html | &)
:: +de-base64url: url-safe base64 decoding, without padding
::
++ de-base64url
~(de base64 | &)
~(de base64:mimes:html | &)
:: |octn: encode/decode unsigned atoms as big-endian octet stream
::
++ octn

View File

@ -1,7 +1,5 @@
:: blit: runtime blit structure
::
/+ base64
::
|_ =blit:dill
++ grad %noun
:: +grab: convert from
@ -30,13 +28,13 @@
%sag
%- pairs
:~ 'path'^(path p.blit)
'file'^s+(en:base64 (as-octs:mimes:html (jam q.blit)))
'file'^s+(en:base64:mimes:html (as-octs:mimes:html (jam q.blit)))
==
::
%sav
%- pairs
:~ 'path'^(path p.blit)
'file'^s+(en:base64 (as-octs:mimes:html q.blit))
'file'^s+(en:base64:mimes:html (as-octs:mimes:html q.blit))
==
::
%klr

View File

@ -3906,34 +3906,140 @@
[(add (dvr (lent a) 2)) (rep [0 4] (flop a))]
(star hit)
--
:: :: ++en-base64:mimes:
++ en-base64 :: encode base64
|= tig=@
^- tape
=+ poc=(~(dif fo 3) 0 (met 3 tig))
=+ pad=(lsh [3 poc] (swp 3 tig))
=+ ^= cha
'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'
=+ ^= sif
|- ^- tape
?~ pad
~
=+ d=(end [0 6] pad)
[(cut 3 [d 1] cha) $(pad (rsh [0 6] pad))]
(weld (flop (slag poc sif)) (reap poc '='))
:: :: ++de-base64:mimes:
++ de-base64 :: decode base64
=- |=(a=cord (rash a fel))
=< fel=(cook |~(a=@ `@t`(swp 3 a)) (bass 64 .))
=- (cook welp ;~(plug (plus siw) (stun 0^2 (cold %0 tis))))
^= siw
;~ pose
(cook |=(a=@ (sub a 'A')) (shim 'A' 'Z'))
(cook |=(a=@ (sub a 'G')) (shim 'a' 'z'))
(cook |=(a=@ (add a 4)) (shim '0' '9'))
(cold 62 (just '+'))
(cold 63 (just '/'))
==
:: |base64: flexible base64 encoding for little-endian atoms
::
++ base64
=> |%
+$ byte @D
+$ word24 @
::
++ div-ceil
:: divide, rounding up.
|= [x=@ y=@] ^- @
?: =(0 (mod x y))
(div x y)
+((div x y))
::
++ explode-bytes
:: Explode a bytestring into list of bytes. Result is in LSB order.
|= =octs ^- (list byte)
=/ atom-byte-width (met 3 q.octs)
=/ leading-zeros (sub p.octs atom-byte-width)
(weld (reap leading-zeros 0) (rip 3 q.octs))
::
++ explode-words
:: Explode a bytestring to words of bit-width `wid`. Result is in LSW order.
|= [wid=@ =octs]
^- (list @)
=/ atom-bit-width (met 0 q.octs)
=/ octs-bit-width (mul 8 p.octs)
=/ atom-word-width (div-ceil atom-bit-width wid)
=/ rslt-word-width (div-ceil octs-bit-width wid)
=/ pad (sub rslt-word-width atom-word-width)
=/ x (rip [0 wid] q.octs)
%+ weld x
(reap pad 0)
--
::
:: pad: include padding when encoding, require when decoding
:: url: use url-safe characters '-' for '+' and '_' for '/'
::
=+ [pad=& url=|]
|%
:: +en:base64: encode +octs to base64 cord
::
:: Encode an `octs` into a base64 string.
::
:: First, we break up the input into a list of 24-bit words. The input
:: might not be a multiple of 24-bits, so we add 0-2 padding bytes at
:: the end (to the least-significant side, with a left-shift).
::
:: Then, we encode each block into four base64 characters.
::
:: Finally we remove the padding that we added at the beginning: for
:: each byte that was added, we replace one character with an = (unless
:: `pad` is false, in which case we just remove the extra characters).
::
++ en
^- $-(octs cord)
::
=/ cha
?: url
'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_'
'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'
::
|^ |= bs=octs ^- cord
=/ [padding=@ blocks=(list word24)]
(octs-to-blocks bs)
(crip (flop (unpad padding (encode-blocks blocks))))
::
++ octs-to-blocks
|= bs=octs ^- [padding=@ud (list word24)]
=/ padding=@ud (~(dif fo 3) 0 p.bs)
=/ padded=octs [(add padding p.bs) (lsh [3 padding] (rev 3 bs))]
[padding (explode-words 24 padded)]
::
++ unpad
|= [extra=@ t=tape] ^- tape
=/ without (slag extra t)
?. pad without
(weld (reap extra '=') without)
::
++ encode-blocks
|= ws=(list word24) ^- tape
(zing (turn ws encode-block))
::
++ encode-block
|= w=word24 ^- tape
=/ a (cut 3 [(cut 0 [0 6] w) 1] cha)
=/ b (cut 3 [(cut 0 [6 6] w) 1] cha)
=/ c (cut 3 [(cut 0 [12 6] w) 1] cha)
=/ d (cut 3 [(cut 0 [18 6] w) 1] cha)
~[a b c d]
--
::
:: +de:base64: decode base64 cord to (unit @)
::
++ de
|= a=cord
^- (unit octs)
(rush a parse)
:: +parse:base64: parse base64 cord to +octs
::
++ parse
=< ^- $-(nail (like octs))
%+ sear reduce
;~ plug
%- plus ;~ pose
(cook |=(a=@ (sub a 'A')) (shim 'A' 'Z'))
(cook |=(a=@ (sub a 'G')) (shim 'a' 'z'))
(cook |=(a=@ (add a 4)) (shim '0' '9'))
(cold 62 (just ?:(url '-' '+')))
(cold 63 (just ?:(url '_' '/')))
==
(stun 0^2 (cold %0 tis))
==
|%
:: +reduce:parse:base64: reduce, measure, and swap base64 digits
::
++ reduce
|= [dat=(list @) dap=(list @)]
^- (unit octs)
=/ lat (lent dat)
=/ lap (lent dap)
=/ dif (~(dif fo 4) 0 lat)
?: &(pad !=(dif lap))
:: padding required and incorrect
~&(%base-64-padding-err-one ~)
?: &(!pad !=(0 lap))
:: padding not required but present
~&(%base-64-padding-err-two ~)
=/ len (sub (mul 3 (div (add lat dif) 4)) dif)
:+ ~ len
%+ swp 3
(rep [0 6] (flop (weld dat (reap dif 0))))
--
--
::
++ en-base58
|= dat=@

View File

@ -1,77 +0,0 @@
/+ base64, *test
:: XX move to zuse
::
|%
++ octn
|%
++ en |=(a=@u `octs`[(met 3 a) (swp 3 a)])
++ de |=(a=octs `@u`(rev 3 p.a q.a))
--
++ en-base64url
~(en base64 | &)
++ de-base64url
~(de base64 | &)
--
::
|%
++ test-explode-bytes
;: weld
%+ expect-eq
!> ~
!> (flop (explode-bytes:base64 [0 `@`0]))
::
%+ expect-eq
!> ~[0x0 0x0 0x0]
!> (flop (explode-bytes:base64 [3 `@`0]))
::
%+ expect-eq
!> ~[0x1 0x1 0x1]
!> (flop (explode-bytes:base64 [3 `@`0x1.0101]))
==
::
++ test-explode-words
;: weld
%+ expect-eq
!> ~
!> (flop (explode-words:base64 1 [0 `@`0]))
::
%+ expect-eq
!> ~[0 0 0 0 0 0 0 1]
!> (flop (explode-words:base64 3 [3 `@`1]))
::
%+ expect-eq
!> ~[0x0 0x12.3456 0x78.9abc 0xde.f012 0x34.5678]
!> =/ inp [15 `@`0x1234.5678.9abc.def0.1234.5678]
(flop (explode-words:base64 24 inp))
==
::
++ test-base64
;: weld
%+ expect-eq
!> 'AQAB'
!> (en-base64url (en:octn 65.537))
::
%+ expect-eq
!> 65.537
!> (de:octn (need (de-base64url 'AQAB')))
::
:: echo "hello" | base64
%+ expect-eq
!> 'aGVsbG8K'
!> (en:base64 (as-octs:mimes:html 'hello\0a'))
::
%+ expect-eq
!> 'hello\0a'
!> +:(need (de:base64 'aGVsbG8K'))
::
:: echo -n -e "\x01\x01\x02\x03" | base64
%+ expect-eq
!> 'AQECAw=='
!> (en:base64 (en:octn 0x101.0203))
::
%+ expect-eq
!> `@t`0x302.0101
!> +:(need (de:base64 'AQECAw=='))
==
--

View File

@ -2,6 +2,20 @@
::
/+ *test
=, mimes:html
:: helpers
::
|%
++ octn
|%
++ en |=(a=@u `octs`[(met 3 a) (swp 3 a)])
++ de |=(a=octs `@u`(rev 3 p.a q.a))
--
++ en-base64url
~(en base64 | &)
++ de-base64url
~(de base64 | &)
--
::
|%
++ test-en-base16
;: weld
@ -61,4 +75,64 @@
!> ^- (unit [@ud @ux])
(de:base16 '001234')
==
::
++ test-explode-bytes
;: weld
%+ expect-eq
!> ~
!> (flop (explode-bytes:base64 [0 `@`0]))
::
%+ expect-eq
!> ~[0x0 0x0 0x0]
!> (flop (explode-bytes:base64 [3 `@`0]))
::
%+ expect-eq
!> ~[0x1 0x1 0x1]
!> (flop (explode-bytes:base64 [3 `@`0x1.0101]))
==
::
++ test-explode-words
;: weld
%+ expect-eq
!> ~
!> (flop (explode-words:base64 1 [0 `@`0]))
::
%+ expect-eq
!> ~[0 0 0 0 0 0 0 1]
!> (flop (explode-words:base64 3 [3 `@`1]))
::
%+ expect-eq
!> ~[0x0 0x12.3456 0x78.9abc 0xde.f012 0x34.5678]
!> =/ inp [15 `@`0x1234.5678.9abc.def0.1234.5678]
(flop (explode-words:base64 24 inp))
==
::
++ test-base64
;: weld
%+ expect-eq
!> 'AQAB'
!> (en-base64url (en:octn 65.537))
::
%+ expect-eq
!> 65.537
!> (de:octn (need (de-base64url 'AQAB')))
::
:: echo "hello" | base64
%+ expect-eq
!> 'aGVsbG8K'
!> (en:base64 (as-octs:mimes:html 'hello\0a'))
::
%+ expect-eq
!> 'hello\0a'
!> +:(need (de:base64 'aGVsbG8K'))
::
:: echo -n -e "\x01\x01\x02\x03" | base64
%+ expect-eq
!> 'AQECAw=='
!> (en:base64 (en:octn 0x101.0203))
::
%+ expect-eq
!> `@t`0x302.0101
!> +:(need (de:base64 'AQECAw=='))
==
--