local byte, char, concat = string.byte, string.char, table.concat local band, bxor, rshift, lshift = bit32.band, bit32.bxor, bit32.rshift, bit32.lshift local wait = function() end local B64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/" local B64R = {} for i = 1, #B64 do B64R[byte(B64, i)] = i - 1 end local function b64(s) local out, cur = {}, {} local acc, bits = 0, 0 for i = 1, #s do local c = byte(s, i) if c == 61 then break end local v = B64R[c] if v then acc = acc * 64 + v bits = bits + 6 if bits >= 8 then bits = bits - 8 cur[#cur + 1] = char(band(rshift(acc, bits), 255)) acc = band(acc, lshift(1, bits) - 1) if #cur >= 4096 then out[#out + 1] = concat(cur); cur = {} end end end end out[#out + 1] = concat(cur) return concat(out) end local function decrypt(s, key) local n = #key if n == 0 then return nil end local out, cur = {}, {} for i = 1, #s do local x = bxor(byte(s, i), byte(key, ((i - 1) % n) + 1)) x = bxor(x, band(i, 255)) x = bxor(x, band(rshift(i, 8), 255)) cur[#cur + 1] = char(x) if #cur >= 4096 then out[#out + 1] = concat(cur); cur = {} end end out[#out + 1] = concat(cur) return concat(out) end local B64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/" local function b64enc(s) local out, cur, cn = {}, {}, 0 local i, len = 1, #s while i + 2 <= len do local a, b, c = byte(s, i, i + 2) local x = a * 65536 + b * 256 + c cn = cn + 1 cur[cn] = string.sub(B64, band(rshift(x, 18), 63) + 1, band(rshift(x, 18), 63) + 1) .. string.sub(B64, band(rshift(x, 12), 63) + 1, band(rshift(x, 12), 63) + 1) .. string.sub(B64, band(rshift(x, 6), 63) + 1, band(rshift(x, 6), 63) + 1) .. string.sub(B64, band(x, 63) + 1, band(x, 63) + 1) if cn >= 4096 then out[#out + 1] = concat(cur); cur = {}; cn = 0 end i = i + 3 end local rem = len - i + 1 if rem > 0 then local a, b = byte(s, i, i + 1) local x = a * 65536 + (b or 0) * 256 cn = cn + 1 cur[cn] = string.sub(B64, band(rshift(x, 18), 63) + 1, band(rshift(x, 18), 63) + 1) .. string.sub(B64, band(rshift(x, 12), 63) + 1, band(rshift(x, 12), 63) + 1) .. (rem == 2 and string.sub(B64, band(rshift(x, 6), 63) + 1, band(rshift(x, 6), 63) + 1) or "=") .. "=" end out[#out + 1] = concat(cur) return concat(out) end local n = 619155 local t = {} for i = 1, n do t[i] = char((i * 37) % 256) end local data = concat(t) local key = "0123456789abcdef0123456789abcdef" local enc = b64enc(data) print("sizes", #data, #enc) local t0 = os.clock(); local d = b64(enc) print("b64", string.format("%.4f", os.clock() - t0), #d, d == data) local t1 = os.clock(); local o = decrypt(data, key) print("dec", string.format("%.4f", os.clock() - t1), #o)