|
1 | | --- Thanks to Tiffany352 for this base64 implementation! |
2 | | - |
3 | | -local floor = math.floor |
4 | | -local char = string.char |
5 | | - |
6 | | -local function encodeBase64(str) |
7 | | - local out = {} |
8 | | - local nOut = 0 |
9 | | - local alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/" |
10 | | - local strLen = #str |
11 | | - |
12 | | - -- 3 octets become 4 hextets |
13 | | - for i = 1, strLen - 2, 3 do |
14 | | - local b1, b2, b3 = str:byte(i, i + 3) |
15 | | - local word = b3 + b2 * 256 + b1 * 256 * 256 |
16 | | - |
17 | | - local h4 = word % 64 + 1 |
18 | | - word = floor(word / 64) |
19 | | - local h3 = word % 64 + 1 |
20 | | - word = floor(word / 64) |
21 | | - local h2 = word % 64 + 1 |
22 | | - word = floor(word / 64) |
23 | | - local h1 = word % 64 + 1 |
24 | | - |
25 | | - out[nOut + 1] = alphabet:sub(h1, h1) |
26 | | - out[nOut + 2] = alphabet:sub(h2, h2) |
27 | | - out[nOut + 3] = alphabet:sub(h3, h3) |
28 | | - out[nOut + 4] = alphabet:sub(h4, h4) |
29 | | - nOut = nOut + 4 |
30 | | - end |
31 | | - |
32 | | - local remainder = strLen % 3 |
33 | | - |
34 | | - if remainder == 2 then |
35 | | - -- 16 input bits -> 3 hextets (2 full, 1 partial) |
36 | | - local b1, b2 = str:byte(-2, -1) |
37 | | - -- partial is 4 bits long, leaving 2 bits of zero padding -> |
38 | | - -- offset = 4 |
39 | | - local word = b2 * 4 + b1 * 4 * 256 |
40 | | - |
41 | | - local h3 = word % 64 + 1 |
42 | | - word = floor(word / 64) |
43 | | - local h2 = word % 64 + 1 |
44 | | - word = floor(word / 64) |
45 | | - local h1 = word % 64 + 1 |
46 | | - |
47 | | - out[nOut + 1] = alphabet:sub(h1, h1) |
48 | | - out[nOut + 2] = alphabet:sub(h2, h2) |
49 | | - out[nOut + 3] = alphabet:sub(h3, h3) |
50 | | - out[nOut + 4] = "=" |
51 | | - elseif remainder == 1 then |
52 | | - -- 8 input bits -> 2 hextets (2 full, 1 partial) |
53 | | - local b1 = str:byte(-1, -1) |
54 | | - -- partial is 2 bits long, leaving 4 bits of zero padding -> |
55 | | - -- offset = 16 |
56 | | - local word = b1 * 16 |
57 | | - |
58 | | - local h2 = word % 64 + 1 |
59 | | - word = floor(word / 64) |
60 | | - local h1 = word % 64 + 1 |
61 | | - |
62 | | - out[nOut + 1] = alphabet:sub(h1, h1) |
63 | | - out[nOut + 2] = alphabet:sub(h2, h2) |
64 | | - out[nOut + 3] = "=" |
65 | | - out[nOut + 4] = "=" |
66 | | - end |
67 | | - -- if the remainder is 0, then no work is needed |
68 | | - |
69 | | - return table.concat(out, "") |
70 | | -end |
71 | | - |
72 | | -local function decodeBase64(str) |
73 | | - local out = {} |
74 | | - local nOut = 0 |
75 | | - local alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/" |
76 | | - local strLen = #str |
77 | | - local acc = 0 |
78 | | - local nAcc = 0 |
79 | | - |
80 | | - local alphabetLut = {} |
81 | | - for i = 1, #alphabet do |
82 | | - alphabetLut[alphabet:sub(i, i)] = i - 1 |
83 | | - end |
84 | | - |
85 | | - -- 4 hextets become 3 octets |
86 | | - for i = 1, strLen do |
87 | | - local ch = str:sub(i, i) |
88 | | - local byte = alphabetLut[ch] |
89 | | - if byte then |
90 | | - acc = acc * 64 + byte |
91 | | - nAcc = nAcc + 1 |
92 | | - end |
93 | | - |
94 | | - if nAcc == 4 then |
95 | | - local b3 = acc % 256 |
96 | | - acc = floor(acc / 256) |
97 | | - local b2 = acc % 256 |
98 | | - acc = floor(acc / 256) |
99 | | - local b1 = acc % 256 |
100 | | - |
101 | | - out[nOut + 1] = char(b1) |
102 | | - out[nOut + 2] = char(b2) |
103 | | - out[nOut + 3] = char(b3) |
104 | | - nOut = nOut + 3 |
105 | | - nAcc = 0 |
106 | | - acc = 0 |
107 | | - end |
108 | | - end |
109 | | - |
110 | | - if nAcc == 3 then |
111 | | - -- 3 hextets -> 16 bit output |
112 | | - acc = acc * 64 |
113 | | - acc = floor(acc / 256) |
114 | | - local b2 = acc % 256 |
115 | | - acc = floor(acc / 256) |
116 | | - local b1 = acc % 256 |
117 | | - |
118 | | - out[nOut + 1] = char(b1) |
119 | | - out[nOut + 2] = char(b2) |
120 | | - elseif nAcc == 2 then |
121 | | - -- 2 hextets -> 8 bit output |
122 | | - acc = acc * 64 |
123 | | - acc = floor(acc / 256) |
124 | | - acc = acc * 64 |
125 | | - acc = floor(acc / 256) |
126 | | - local b1 = acc % 256 |
127 | | - |
128 | | - out[nOut + 1] = char(b1) |
129 | | - elseif nAcc == 1 then |
130 | | - error("Base64 has invalid length") |
131 | | - end |
132 | | - |
133 | | - return table.concat(out, "") |
134 | | -end |
| 1 | +local EncodingService = game:GetService("EncodingService") |
135 | 2 |
|
136 | 3 | return { |
137 | | - decode = decodeBase64, |
138 | | - encode = encodeBase64, |
| 4 | + decode = function(input: string) |
| 5 | + return buffer.tostring(EncodingService:Base64Decode(buffer.fromstring(input))) |
| 6 | + end, |
| 7 | + encode = function(input: string) |
| 8 | + return buffer.tostring(EncodingService:Base64Encode(buffer.fromstring(input))) |
| 9 | + end, |
139 | 10 | } |
0 commit comments