Lua Base64自定义编解码
Posted 抚琴一生
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Lua Base64自定义编解码相关的知识,希望对你有一定的参考价值。
一、背景
最近在研究如何使用纯lua实现base64自定义码表编解码,记录一下。一起探讨下。
二、代码实现
1、base64编码
-- 自定义编码表
local encodeTable = { [0] =
'A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P',
'Q','R','S','T','U','V','W','X','Y','Z','a','b','c','d','e','f',
'g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v',
'w','x','y','z','0','1','2','3','4','5','6','7','8','9','+','/',
}
-- 字符串编码
local function base64Encode(s)
local bs = encodeTable
local byte, rep = string.byte, string.rep
local pad = 2 - ((#s-1) % 3)
s = (s..rep('\\0', pad)):gsub("...", function(cs)
local a, b, c = byte(cs, 1, 3)
return bs[a>>2] .. bs[(a&3)<<4|b>>4] .. bs[(b&15)<<2|c>>6] .. bs[c&63]
end)
return s:sub(1, #s-pad) .. rep('=', pad)
end
2、base64解码
参考:http://www.ruanyifeng.com/blog/2008/06/base64.html
-- 自定义解码表
local decodeTable = { [0] =
'A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P',
'Q','R','S','T','U','V','W','X','Y','Z','a','b','c','d','e','f',
'g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v',
'w','x','y','z','0','1','2','3','4','5','6','7','8','9','+','/',
}
local decodeArr = {[0] =
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 62, -1, -1, -1, 63,
52, 53, 54, 55, 56, 57, 58, 59, 60, 61, -1, -1, -1, -1, -1, -1,
-1, 0, 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, -1, -1, -1, -1, -1,
-1, 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, -1, -1, -1, -1, -1
}
-- 字节转换
local function transferBytes(arr)
local ss = {}
local k = 1
while true do
if k > #arr then break end
local c = arr[k]
if not c then break end
if c<192 then
table.insert(ss, string.char(c))
k = k + 1
elseif c<224 then
k = k + 2
elseif c<240 then
if c>=228 and c<=233 then
local c1 = arr[k+1]
local c2 = arr[k+2]
if c1 and c2 then
local a1,a2,a3,a4 = 128,191,128,191
if c == 228 then a1 = 184
elseif c == 233 then a2,a4 = 190,c1 ~= 190 and 191 or 165
end
if c1>=a1 and c1<=a2 and c2>=a3 and c2<=a4 then
table.insert(ss, string.char(c,c1,c2))
end
end
end
k = k + 3
elseif c<248 then
k = k + 4
elseif c<252 then
k = k + 5
elseif c<254 then
k = k + 6
end
end
return table.concat(ss)
end
-- 字符串解码
local function base64Decode(s)
local bs = decodeTable
local byte, rep = string.byte, string.rep
local pad = 0
local lastTwoString = string.sub(s, -2)
local lastString = string.sub(s, -1)
if lastTwoString == '==' then
pad = 2
elseif lastString == '=' then
pad = 1
end
s = (s..rep('\\0', pad)):gsub('....', function (cs)
local a, b, c, d = byte(cs, 1, 4)
local aStr, bStr, cStr, dStr = '', '', '', ''
if decodeArr[a] and bs[decodeArr[a]] then
aStr = bs[decodeArr[a]]
end
if decodeArr[b] and bs[decodeArr[b]] then
bStr = bs[decodeArr[b]]
end
if decodeArr[c] and bs[decodeArr[c]] then
cStr = bs[decodeArr[c]]
end
if decodeArr[d] and bs[decodeArr[d]] then
dStr = bs[decodeArr[d]]
end
return aStr .. bStr .. cStr .. dStr
end)
-- 自定义码表转换后的字符串
local newStr = s:sub(1, #s-pad) .. rep('=', pad)
local c1, c2, c3, c4 = -1, -1, -1, -1
local len = #newStr
local decodeStr = ''
local i = 1
local byteArr = {}
local byteA, byteB, byteC = 0, 0, 0
while i <= len do
-- c1
while i <= len do
c1 = decodeArr[byte(newStr, i, i+1)] & 0xff
i = i + 1
if c1 ~= -1 then
break
end
end
if c1 == -1 then
break
end
-- c2
while i <= len do
c2 = decodeArr[byte(newStr, i, i+1)] & 0xff
i = i + 1
if c2 ~= -1 then
break
end
end
if c2 == -1 then
break
end
byteA = (c1<<2)|(c2&0x30)>>4
table.insert(byteArr, byteA)
-- c3
while i <= len do
c3 = byte(newStr, i, i+1) & 0xff
i = i + 1
if c3 == 61 then
return decodeStr
end
c3 = decodeArr[c3]
if c3 ~= -1 then
break
end
end
if c3 == -1 then
break
end
byteB = ((c2&0xF)<<4)|((c3&0x3C)>>2)
table.insert(byteArr, byteB)
-- c4
while i <= len do
c4 = byte(newStr, i, i+1) & 0xff
i = i + 1
if c4 == 61 then
return decodeStr
end
c4 = decodeArr[c4]
if c4 ~= -1 then
break
end
end
if c4 == -1 then
break
end
byteC = ((c3&0x03)<<6)|c4
table.insert(byteArr, byteC)
end
decodeStr = transferBytes(byteArr)
return decodeStr
end
以上是关于Lua Base64自定义编解码的主要内容,如果未能解决你的问题,请参考以下文章