博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Lua Base64自定义编解码
阅读量:3787 次
发布时间:2019-05-22

本文共 4928 字,大约阅读时间需要 16 分钟。

一、背景

最近在研究如何使用纯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解码

参考:

-- 自定义解码表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 decodeStrend

转载地址:http://pdktn.baihongyu.com/

你可能感兴趣的文章
史上最全的集合(集合UML图(Collection集合和Map集合)详解,子接口(list和set)泛型)
查看>>
IO流(字节流和字符流)
查看>>
P1563 玩具谜题
查看>>
L1-002 打印沙漏 (20分)
查看>>
P1217 [USACO1.5]回文质数 Prime Palindromes
查看>>
P1014 Cantor表
查看>>
实验十 算术编码
查看>>
实验二 二维随机变量信息量的计算
查看>>
使用react脚手架创建react项目时发生错误
查看>>
关于setState是异步与同步的
查看>>
56. 合并区间---js解法
查看>>
5. 最长回文子串---js解法
查看>>
USACO 2007 Open Gold/acwing2240:餐饮 (拆点+最大流)‘三分图匹配’
查看>>
那些年你不知道的C++STL进制转换函数
查看>>
区间和并问题 思路加模板整理(校门外的树)
查看>>
C++中next_permutation函数的使用方法、原理及手动实现
查看>>
网络流常用小技巧之 拆点
查看>>
最大权闭合子图
查看>>
最小权点覆盖集 与 最大权独立集
查看>>
POJ 2125 Destroying The Graph && Acwing 2325. 有向图破坏(拆点+最小权点覆盖集)
查看>>