local cb64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/" b64 = {} local function istr(p) return string.sub(cb64, p + 1, p + 1) end function b64.encodeblock(in_tab, len) local s1, s2, s3, s4 in_tab[0] = in_tab[1] or 0 in_tab[1] = in_tab[2] or 0 in_tab[2] = in_tab[3] or 0 s1 = istr(bin.rshift(in_tab[0], 2)) s2 = istr(bin.bor(bin.lshift(bin.band(in_tab[0], 3), 4), bin.rshift(bin.band(in_tab[1], 240), 4))) s3 = (len > 1 and istr(bin.bor(bin.lshift(bin.band(in_tab[1], 15), 2), bin.rshift(bin.band(in_tab[2], 192), 6))) or "=") s4 = (len > 2 and istr( bin.band(in_tab[2], 63)) or "=") return s1..s2..s3..s4 end function b64.encode(stream, stream_size) local encoded = "" local e_block local in_tab, len, i, s_pos s_pos = 0 while stream_size > 0 do in_tab = {} len = stream_size >= 3 and 3 or stream_size for i = 1, len do in_tab[i] = stream[s_pos + i] end e_block = b64.encodeblock(in_tab, len) encoded = encoded .. e_block s_pos = s_pos + 3 stream_size = stream_size - 3 end return encoded end local function stri(s) return s == "=" and -1 or (string.find(cb64, s) - 1) end function b64.decodeblock(s1, s2, s3, s4) local b1, b2, b3, len len = s3 == "=" and 1 or s4 == "=" and 2 or 3 s3 = s3 == "=" and "A" or s3 s4 = s4 == "=" and "A" or s4 s1 = stri(s1) s2 = stri(s2) s3 = stri(s3) s4 = stri(s4) b1 = bin.bor(bin.lshift(s1, 2), bin.rshift(s2, 4)) b2 = bin.bor(bin.band(bin.lshift(s2, 4), 255), bin.rshift(s3, 2)) b3 = bin.bor(bin.band(bin.lshift(s3, 6), 240), s4) return {b1, b2, b3}, len end function b64.decode(str_in) local s_len = string.len(str_in) / 4 local out, len, i, j, t_out, s1, s2, s3, s4, t_len = {}, 0 for i = 1, s_len do s1 = string.sub(str_in, i * 4 - 3, i * 4 - 3) s2 = string.sub(str_in, i * 4 - 2, i * 4 - 2) s3 = string.sub(str_in, i * 4 - 1, i * 4 - 1) s4 = string.sub(str_in, i * 4 - 0, i * 4 - 0) t_out, t_len = b64.decodeblock(s1, s2, s3, s4) for j = 1, t_len do out[i * 3 - 3 + j] = t_out[j] end len = len + t_len end return out, len end --[[ b64_test_in = { 48, 49, 50, 51, 52, 53, 54, 55, 56, 57 } b64_test_enc = "MDEyMzQ1Njc4OQ==" function test_b64() local enc, dec, i, len enc = b64.encode(b64_test_in, 10) assert(enc == b64_test_enc) dec, len = b64.decode(enc) assert(len == 10) for i = 1, len do assert(b64_test_in[i] == dec[i]) end end ]]