local V={}local G={}for G=65,90,1 do table.insert(V,G)end for G=97,122,1 do table.insert(V,G)end for G=48,57,1 do table.insert(V,G)end table.insert(V,43)table.insert(V,47)for V,v in ipairs(V)do G[v]=V end local v={}local B=bit32.rshift local g=bit32.lshift local m=bit32.band function v.Encode(G)local v={}local X=0 for F=1,#G,3 do local P,Y,x=string.byte(G,F,F+2)local j=B(P,2)local Z=g(m(P,3),4)+B(Y or 0,4)local l=g(m(Y or 0,15),2)+B(x or 0,6)local d=m(x or 0,63)X=X+1 v[X]=V[j+1]X=X+1 v[X]=V[Z+1]X=X+1 v[X]=Y and V[l+1]or 61 X=X+1 v[X]=x and V[d+1]or 61 end local F={}local P=0 local Y for V=1,X,4096 do P=P+1 Y=(V+4096)-1 F[P]=string.char(table.unpack(v,V,Y>X and X or Y))end return table.concat(F)end function v.Decode(V)local v={}local X=0 for F=1,#V,4 do local P,Y,x,j=string.byte(V,F,F+3)local Z=G[P]-1 local l=G[Y]-1 local d=(G[x]or 1)-1 local M=(G[j]or 1)-1 local R=g(Z,2)+B(l,4)local K=g(m(l,15),4)+B(d,2)local o=g(m(d,3),6)+M X=X+1 v[X]=R if x~=61 then X=X+1 v[X]=K end if j~=61 then X=X+1 v[X]=o end end local F={}local P=0 local Y for V=1,X,4096 do P=P+1 Y=(V+4096)-1 F[P]=string.char(table.unpack(v,V,Y>X and X or Y))end return table.concat(F)end return v
-- @original: https://gist.github.com/Reselim/40d62b17d138cc74335a1b0709e19ce2
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 = {}

local bit32_rshift = bit32.rshift
local bit32_lshift = bit32.lshift
local bit32_band = bit32.band

--[[**
	Encodes a string in Base64.
	@param [t:string] Input The input string to encode.
	@returns [t:string] The string encoded in Base64.
**--]]
function Base64.Encode(Input)
	local Output = {}
	local Length = 0

	for Index = 1, #Input, 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)

		Length = Length + 1
		Output[Length] = Alphabet[A + 1]

		Length = Length + 1
		Output[Length] = Alphabet[B + 1]

		Length = Length + 1
		Output[Length] = C2 and Alphabet[C + 1] or 61

		Length = Length + 1
		Output[Length] = C3 and Alphabet[D + 1] or 61
	end

	local NewOutput = {}
	local NewLength = 0
	local IndexAdd4096Sub1

	for Index = 1, Length, 4096 do
		NewLength = NewLength + 1
		IndexAdd4096Sub1 = Index + 4096 - 1

		NewOutput[NewLength] = string.char(table.unpack(
			Output,
			Index,
			IndexAdd4096Sub1 > Length and Length or IndexAdd4096Sub1
		))
	end

	return table.concat(NewOutput)
end

--[[**
	Decodes a string from Base64.
	@param [t:string] Input The input string to decode.
	@returns [t: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 = Length + 1
		Output[Length] = A

		if C3 ~= 61 then
			Length = Length + 1
			Output[Length] = B
		end

		if C4 ~= 61 then
			Length = Length + 1
			Output[Length] = C
		end
	end

	local NewOutput = {}
	local NewLength = 0
	local IndexAdd4096Sub1

	for Index = 1, Length, 4096 do
		NewLength = NewLength + 1
		IndexAdd4096Sub1 = Index + 4096 - 1

		NewOutput[NewLength] = string.char(table.unpack(
			Output,
			Index,
			IndexAdd4096Sub1 > Length and Length or IndexAdd4096Sub1
		))
	end

	return table.concat(NewOutput)
end

return Base64