@@ -10,111 +10,111 @@ for i = 1, #b64c do dt[b64c:sub(i,i)] = i - 1 end
1010--- @return string The base64 string
1111function base64_encode_file (file )
1212
13- -- r = result
14- -- l = length
15- local r , l = {}, 0
16-
17- while true do
18-
19- -- c = chunk of 3 bytes
20- local c = file :read (3 )
21- if not c or # c == 0 then break end
22-
23- -- Pad chunk to 3 bytes if needed
24- -- pa = padded
25- -- p = pad length
26- local p = 3 - # c
27- for _ = 1 , p do
28- c = c .. ' \0 '
29- end
30-
31- -- Convert 3 bytes to 4 base64 characters
32- local b1 , b2 , b3 , c1 , c2 , c3 , c4 = c :byte (1 , 3 )
33- local n = (b1 << 16 ) + (b2 << 8 ) + b3
34-
35- c1 = b64c :sub (((n >> 18 ) & 63 ) + 1 , ((n >> 18 ) & 63 ) + 1 )
36- c2 = b64c :sub (((n >> 12 ) & 63 ) + 1 , ((n >> 12 ) & 63 ) + 1 )
37- c3 = b64c :sub (((n >> 6 ) & 63 ) + 1 , ((n >> 6 ) & 63 ) + 1 )
38- c4 = b64c :sub ((n & 63 ) + 1 , (n & 63 ) + 1 )
39-
40- -- Apply padding
41- if p == 1 then
42- c4 = ' ='
43- elseif p == 2 then
44- c3 = ' ='
45- c4 = ' ='
46- end
47-
48- local en = c1 .. c2 .. c3 .. c4
49- table.insert (r , en )
50-
51- l = l + 4
52- if l >= 76 then -- Standard base64 line length
53- table.insert (r , ' \n ' )
54- l = 0
55- end
56- end
57-
58- return table.concat (r )
13+ -- r = result
14+ -- l = length
15+ local r , l = {}, 0
16+
17+ while true do
18+
19+ -- c = chunk of 3 bytes
20+ local c = file :read (3 )
21+ if not c or # c == 0 then break end
22+
23+ -- Pad chunk to 3 bytes if needed
24+ -- pa = padded
25+ -- p = pad length
26+ local p = 3 - # c
27+ for _ = 1 , p do
28+ c = c .. ' \0 '
29+ end
30+
31+ -- Convert 3 bytes to 4 base64 characters
32+ local b1 , b2 , b3 , c1 , c2 , c3 , c4 = c :byte (1 , 3 )
33+ local n = (b1 << 16 ) + (b2 << 8 ) + b3
34+
35+ c1 = b64c :sub (((n >> 18 ) & 63 ) + 1 , ((n >> 18 ) & 63 ) + 1 )
36+ c2 = b64c :sub (((n >> 12 ) & 63 ) + 1 , ((n >> 12 ) & 63 ) + 1 )
37+ c3 = b64c :sub (((n >> 6 ) & 63 ) + 1 , ((n >> 6 ) & 63 ) + 1 )
38+ c4 = b64c :sub ((n & 63 ) + 1 , (n & 63 ) + 1 )
39+
40+ -- Apply padding
41+ if p == 1 then
42+ c4 = ' ='
43+ elseif p == 2 then
44+ c3 = ' ='
45+ c4 = ' ='
46+ end
47+
48+ local en = c1 .. c2 .. c3 .. c4
49+ table.insert (r , en )
50+
51+ l = l + 4
52+ if l >= 76 then -- Standard base64 line length
53+ table.insert (r , ' \n ' )
54+ l = 0
55+ end
56+ end
57+
58+ return table.concat (r )
5959end
6060
6161--- Decode a file from base64
6262--- @param file file The file containing the base64 string to decode
6363--- @return string The decoded raw data
6464function base64_decode_file (file )
6565
66- -- r = result
67- -- b = buffer
68- local r , b = {}, " "
69-
70- -- Read all data and remove whitespace/newlines
71- while true do
72-
73- -- l = line
74- local l = file :read (" l" )
75-
76- if not l then break end
77- b = b .. l :gsub (" [^" .. b64c .. " =]" , " " )
78- end
79-
80- -- Process 4 characters at a time
81- for i = 1 , # b , 4 do
82-
83- -- c = chunk of 3 bytes
84- -- b1 = byte 1
85- -- b2 = byte 2
86- -- b3 = byte 3
87- -- b4 = byte 4
88- -- c1 = chunk 1
89- -- c2 = chunk 2
90- -- c3 = chunk 3
91- local c , b1 , b2 , b3 , b4 , n , c1 , c2 , c3 = b :sub (i , i + 3 )
92- if # c < 4 then break end
93-
94- b1 , b2 , b3 , b4 = dt [c :sub (1 ,1 )] or 0 , dt [c :sub (2 ,2 )] or 0 , dt [c :sub (3 ,3 )] or 0 , dt [c :sub (4 ,4 )] or 0
95- n = (b1 << 18 ) + (b2 << 12 ) + (b3 << 6 ) + b4
96- c1 , c2 , c3 = string.char ((n >> 16 ) & 255 ), string.char ((n >> 8 ) & 255 ), string.char (n & 255 )
97-
98- -- Handle padding
99- if c :sub (4 ,4 ) == ' =' then
100- if c :sub (3 ,3 ) == ' =' then
101- table.insert (r , c1 ) -- Only first byte
102- else
103- table.insert (r , c1 .. c2 ) -- First two bytes
104- end
105- else
106- table.insert (r , c1 .. c2 .. c3 ) -- All three bytes
107- end
108- end
109-
110- return table.concat (r )
66+ -- r = result
67+ -- b = buffer
68+ local r , b = {}, " "
69+
70+ -- Read all data and remove whitespace/newlines
71+ while true do
72+
73+ -- l = line
74+ local l = file :read (" l" )
75+
76+ if not l then break end
77+ b = b .. l :gsub (" [^" .. b64c .. " =]" , " " )
78+ end
79+
80+ -- Process 4 characters at a time
81+ for i = 1 , # b , 4 do
82+
83+ -- c = chunk of 3 bytes
84+ -- b1 = byte 1
85+ -- b2 = byte 2
86+ -- b3 = byte 3
87+ -- b4 = byte 4
88+ -- c1 = chunk 1
89+ -- c2 = chunk 2
90+ -- c3 = chunk 3
91+ local c , b1 , b2 , b3 , b4 , n , c1 , c2 , c3 = b :sub (i , i + 3 )
92+ if # c < 4 then break end
93+
94+ b1 , b2 , b3 , b4 = dt [c :sub (1 ,1 )] or 0 , dt [c :sub (2 ,2 )] or 0 , dt [c :sub (3 ,3 )] or 0 , dt [c :sub (4 ,4 )] or 0
95+ n = (b1 << 18 ) + (b2 << 12 ) + (b3 << 6 ) + b4
96+ c1 , c2 , c3 = string.char ((n >> 16 ) & 255 ), string.char ((n >> 8 ) & 255 ), string.char (n & 255 )
97+
98+ -- Handle padding
99+ if c :sub (4 ,4 ) == ' =' then
100+ if c :sub (3 ,3 ) == ' =' then
101+ table.insert (r , c1 ) -- Only first byte
102+ else
103+ table.insert (r , c1 .. c2 ) -- First two bytes
104+ end
105+ else
106+ table.insert (r , c1 .. c2 .. c3 ) -- All three bytes
107+ end
108+ end
109+
110+ return table.concat (r )
111111end
112112
113113if # arg < 1 or # arg > 2 then
114- print (arg [0 ] .. [[ [-e|-d] [file]
115- -e: encode (default)
116- -d: decode"]] )
117- os.exit (1 )
114+ print (arg [0 ] .. [[ [-e|-d] [file]
115+ -e: encode (default)
116+ -d: decode"]] )
117+ os.exit (1 )
118118end
119119
120120-- em = encode mode
@@ -123,36 +123,36 @@ end
123123local em , fn , f = 1
124124
125125for _ , v in ipairs (arg ) do
126- if v == " -d" then
127- em = nil
128- else
129- fn = v
130- end
126+ if v == " -d" then
127+ em = nil
128+ else
129+ fn = v
130+ end
131131end
132132
133133if fn then
134- f , e = io.open (fn , " rb" )
135- if not f then
136- print (e )
137- os.exit (1 )
138- end
134+ f , e = io.open (fn , " rb" )
135+ if not f then
136+ print (e )
137+ os.exit (1 )
138+ end
139139else
140- f , e = io.stdin
140+ f , e = io.stdin
141141end
142142
143143if not f then print (e ) exit (1 ) end
144144
145145if em then
146- local encoded = base64_encode_file (f )
147- io.write (encoded )
148- if not encoded :sub (- 1 ):match (' \n ' ) then
149- io.write (' \n ' )
150- end
146+ local encoded = base64_encode_file (f )
147+ io.write (encoded )
148+ if not encoded :sub (- 1 ):match (' \n ' ) then
149+ io.write (' \n ' )
150+ end
151151else
152- io.write (base64_decode_file (f ))
152+ io.write (base64_decode_file (f ))
153153end
154154
155155-- Close file if it was opened
156156if fn then
157- f :close ()
157+ f :close ()
158158end
0 commit comments