-
Notifications
You must be signed in to change notification settings - Fork 5
/
base64.lua
85 lines (72 loc) · 3.18 KB
/
base64.lua
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
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
-- working lua base64 codec (c) 2006-2008 by Alex Kloss
-- compatible with lua 5.0
-- http://www.it-rfc.de
-- licensed under the terms of the LGPL2
-- bitshift functions (<<, >> equivalent)
-- shift left
local string = string
local math = math
local mod = math.mod
local floor = math.floor
local strlen = string.len
local strbyte = string.byte
local strformat = string.format
local strchar = string.char
local strsub = string.sub
local function lsh(value,shift)
return mod((value*(2^shift)), 256)
end
-- shift right
local function rsh(value,shift)
return mod(floor(value/2^shift), 256)
end
-- return single bit (for OR)
local function bit(x,b)
return (mod(x, 2^b) - mod(x, 2^(b-1)) > 0)
end
-- logic OR for number values
local function lor(x,y)
result = 0
for p=1,8 do result = result + (((bit(x,p) or bit(y,p)) == true) and 2^(p-1) or 0) end
return result
end
-- encryption table
local base64chars = {[0]='A',[1]='B',[2]='C',[3]='D',[4]='E',[5]='F',[6]='G',[7]='H',[8]='I',[9]='J',[10]='K',[11]='L',[12]='M',[13]='N',[14]='O',[15]='P',[16]='Q',[17]='R',[18]='S',[19]='T',[20]='U',[21]='V',[22]='W',[23]='X',[24]='Y',[25]='Z',[26]='a',[27]='b',[28]='c',[29]='d',[30]='e',[31]='f',[32]='g',[33]='h',[34]='i',[35]='j',[36]='k',[37]='l',[38]='m',[39]='n',[40]='o',[41]='p',[42]='q',[43]='r',[44]='s',[45]='t',[46]='u',[47]='v',[48]='w',[49]='x',[50]='y',[51]='z',[52]='0',[53]='1',[54]='2',[55]='3',[56]='4',[57]='5',[58]='6',[59]='7',[60]='8',[61]='9',[62]='-',[63]='_'}
-- function encode
-- encodes input string to base64.
local function enc(data)
local bytes = {}
local result = ""
for spos=0,strlen(data)-1,3 do
for byte=1,3 do bytes[byte] = strbyte(strsub(data,(spos+byte))) or 0 end
result = strformat('%s%s%s%s%s',
result,
base64chars[rsh(bytes[1],2)],
base64chars[lor(lsh((mod(bytes[1], 4)),4), rsh(bytes[2],4))] or "=",
((strlen(data)-spos) > 1) and base64chars[lor(lsh(
mod(bytes[2], 16)
,2), rsh(bytes[3],6))] or "=",
((strlen(data)-spos) > 2) and base64chars[(mod(bytes[3], 64))] or "="
)
end
return result
end
-- decryption table
local base64bytes = {['A']=0,['B']=1,['C']=2,['D']=3,['E']=4,['F']=5,['G']=6,['H']=7,['I']=8,['J']=9,['K']=10,['L']=11,['M']=12,['N']=13,['O']=14,['P']=15,['Q']=16,['R']=17,['S']=18,['T']=19,['U']=20,['V']=21,['W']=22,['X']=23,['Y']=24,['Z']=25,['a']=26,['b']=27,['c']=28,['d']=29,['e']=30,['f']=31,['g']=32,['h']=33,['i']=34,['j']=35,['k']=36,['l']=37,['m']=38,['n']=39,['o']=40,['p']=41,['q']=42,['r']=43,['s']=44,['t']=45,['u']=46,['v']=47,['w']=48,['x']=49,['y']=50,['z']=51,['0']=52,['1']=53,['2']=54,['3']=55,['4']=56,['5']=57,['6']=58,['7']=59,['8']=60,['9']=61,['-']=62,['_']=63,['=']=nil}
-- function decode
-- decode base64 input to string
local function dec(data)
local chars = {}
local result=""
for dpos=0,strlen(data)-1,4 do
for char=1,4 do chars[char] = base64bytes[(strsub(data,(dpos+char),(dpos+char)) or "=")] end
result = strformat('%s%s%s%s',
result,
strchar(lor(lsh(chars[1],2), rsh(chars[2],4))),
(chars[3] ~= nil) and strchar(lor(lsh(chars[2],4), rsh(chars[3],2))) or "",
(chars[4] ~= nil) and strchar(lor(mod(lsh(chars[3],6), 192), (chars[4]))) or ""
)
end
return result
end
return {encode = enc,decode = dec}