summary refs log tree commit diff
path: root/base64.joy
blob: f5216c49b19371a0f3dc7a43a0026a7d573553d7 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
DEFINE
shl == 2 *;
shr == 2 /;
and63 == [64 / 64 *] nullary -;
b64enc1 == ord 16 [shl] times [ord 8 [shl] times] dip + [ord] dip +;
b64enc2 == "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/" swap [] [
		[18 [shr] times and63 at]
		[12 [shr] times and63 at]
		[6  [shr] times and63 at]
		[and63 at]
	      ] construct "" cons cons cons cons [pop] dip;

s2l == [null]  [pop []]  [uncons]  [cons]  linrec;
b64enc ==
	  s2l
          "" swap
	  # pad with null bytes
          # calculate how many bytes to pad
	  [size 3 rem 3 swap - 3 rem] nullary
	  # save the amount for later
	  dup [swap] dip [[swap] dip] dip
	  # i cant use null bytes
	  [0 chr [] cons concat] times
	  # len(s)/3 times
	  [size 3 /] nullary
	  [[3 take] nullary s2l [b64enc1 b64enc2] infra first rollup [swap concat] dip 3 drop] times
	  # remove the now-empty string
	  pop
	  # add the padding
	  # encoded characters - characters that need to be padded
	  [size] nullary swapd [swap -] unary
	  # take only the non padded characters
	  swapd take
	  # add back as many ='s as you took

	  # for some reason this part crahes joy with a malloc error if the input is more than 20 characters
	  swap ["=" concat] times
	  "\n" concat
END
stdin [feof not] [fgets b64enc putchars] while fclose.