This repository has been archived by the owner on Jul 28, 2022. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 57
/
Base64.lua
151 lines (115 loc) · 3.42 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
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
--- Base64
-- Encodes and decodes values to and from Base64
-- @author antifragileer <https://www.roblox.com/users/443282130/profile>
-- @see Developed for the Aero Game Framework <https://github.com/Sleitnick/AeroGameFramework>
-- @see Adapted from https://github.com/toastdriven/lua-base64 for the Roblox game.
-- @see Re-adapted from https://gist.github.com/howmanysmall/016a35f0debcfb81f14e6bee03d450de and https://gist.github.com/Reselim/40d62b17d138cc74335a1b0709e19ce2.
-- @license BSD
-- July 15, 2018
--[[
local base64 = Base64.new()
Example:
local myEncodedWord = base64:Encode("Hello")
print(myEncodedWord)
-- outputs: SGVsbG8=
print(base64:Decode(myEncodedWord))
-- outputs: Hello
--]]
local Alphabet = {}
local Indexes = {}
-- A-Z
for Index = 65, 90 do
table.insert(Alphabet, Index)
end
-- a-z
for Index = 97, 122 do
table.insert(Alphabet, Index)
end
-- 0-9
for Index = 48, 57 do
table.insert(Alphabet, Index)
end
table.insert(Alphabet, 43) -- +
table.insert(Alphabet, 47) -- /
for Index, Character in ipairs(Alphabet) do
Indexes[Character] = Index
end
local Base64 = {
ClassName = "Base64";
__tostring = function(self)
return self.ClassName
end;
}
Base64.__index = Base64
local bit32_rshift = bit32.rshift
local bit32_lshift = bit32.lshift
local bit32_band = bit32.band
function Base64.new()
return setmetatable({}, Base64)
end
--[[**
Encodes a string in Base64.
@param [string] Input The input string to encode.
@returns [string] The string encoded in Base64.
**--]]
function Base64:Encode(Input)
local InputLength = #Input
local Output = table.create(4 * math.floor((InputLength - 1) / 3) + 4) -- Credit to AstroCode for finding the formula.
local Length = 0
for Index = 1, InputLength, 3 do
local C1, C2, C3 = string.byte(Input, Index, Index + 2)
local A = bit32_rshift(C1, 2)
local B = bit32_lshift(bit32_band(C1, 3), 4) + bit32_rshift(C2 or 0, 4)
local C = bit32_lshift(bit32_band(C2 or 0, 15), 2) + bit32_rshift(C3 or 0, 6)
local D = bit32_band(C3 or 0, 63)
Output[Length + 1] = Alphabet[A + 1]
Output[Length + 2] = Alphabet[B + 1]
Output[Length + 3] = C2 and Alphabet[C + 1] or 61
Output[Length + 4] = C3 and Alphabet[D + 1] or 61
Length += 4
end
local NewOutput = {}
local NewLength = 0
for Index = 1, Length, 4096 do
NewLength += 1
NewOutput[NewLength] = string.char(table.unpack(Output, Index, math.min(Index + 4096 - 1, Length)))
end
return table.concat(NewOutput)
end
--[[**
Decodes a string from Base64.
@param [string] Input The input string to decode.
@returns [string] The newly decoded string.
**--]]
function Base64:Decode(Input)
local Output = {}
local Length = 0
for Index = 1, #Input, 4 do
local C1, C2, C3, C4 = string.byte(Input, Index, Index + 3)
local I1 = Indexes[C1] - 1
local I2 = Indexes[C2] - 1
local I3 = (Indexes[C3] or 1) - 1
local I4 = (Indexes[C4] or 1) - 1
local A = bit32_lshift(I1, 2) + bit32_rshift(I2, 4)
local B = bit32_lshift(bit32_band(I2, 15), 4) + bit32_rshift(I3, 2)
local C = bit32_lshift(bit32_band(I3, 3), 6) + I4
Length += 1
Output[Length] = A
if C3 ~= 61 then
Length += 1
Output[Length] = B
end
if C4 ~= 61 then
Length += 1
Output[Length] = C
end
end
local NewOutput = {}
local NewLength = 0
for Index = 1, Length, 4096 do
NewLength += 1
NewOutput[NewLength] = string.char(table.unpack(Output, Index, math.min(Index + 4096 - 1, Length)))
end
return table.concat(NewOutput)
end
return Base64