下面的 base64 加解密代码,对于如何在不使用实际的位移位或运算符的情况下执行逻辑操作很有价值。话不多说上代码:

-- character table string
local b='ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'

-- encoding
local function enc(data)
    return ((data:gsub('.', function(x) 
        local r,b='',x:byte()
        for i=8,1,-1 do r=r..(b%2^i-b%2^(i-1)>0 and '1' or '0') end
        return r;
    end)..'0000'):gsub('%d%d%d?%d?%d?%d?', function(x)
        if (#x < 6) then return '' end
        local c=0
        for i=1,6 do c=c+(x:sub(i,i)=='1' and 2^(6-i) or 0) end
        return b:sub(c+1,c+1)
    end)..({ '', '==', '=' })[#data%3+1])
end

-- decoding
local function dec(data)
    data = string.gsub(data, '[^'..b..'=]', '')
    return (data:gsub('.', function(x)
        if (x == '=') then return '' end
        local r,f='',(b:find(x)-1)
        for i=6,1,-1 do r=r..(f%2^i-f%2^(i-1)>0 and '1' or '0') end
        return r;
    end):gsub('%d%d%d?%d?%d?%d?%d?%d?', function(x)
        if (#x ~= 8) then return '' end
        local c=0
        for i=1,8 do c=c+(x:sub(i,i)=='1' and 2^(8-i) or 0) end
        return string.char(c)
    end))
end

local enc_data = enc("8da8f3ae28ee4f6f95d0d1ba991f7baa")
local dec_data = dec(enc_data)

在 Lua5.3 中使用新二进制操作符加速应用程序中的 base64 编码,我认为这个算法是最优的。每三个输入字节被映射到四个输出字节使用二进制操作如下:

        a                   b                   c
 +-----------------+-----------------+-----------------+
 | 0 0 0 0 0 0 1 1 | 1 1 1 1 2 2 2 2 | 2 2 3 3 3 3 3 3 |
 +|- - - - - -|- - + - - - -|- - - - + - -|- - - - - -|+
 /           /              |              \           \
/           /               |               \           \
    a>>2     (a&3)<<4|b>>4    (b&15)<<2|c>>6      c&63

输入被填充为三个字节的倍数,带有 '=' 的输出填充在计算填充的输入字符串的 base64 后被修复。

local bs = { [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 base64(s)
   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


assert(base64("") == "")
assert(base64("f") == "Zg==")
assert(base64("fo") == "Zm8=")
assert(base64("foo") == "Zm9v")
assert(base64("foob") == "Zm9vYg==")
assert(base64("fooba") == "Zm9vYmE=")
assert(base64("foobar") == "Zm9vYmFy")

附上:
Lua 5.2 base64 encoding/decoding:https://github.com/ErnieE5/ee5_base64
lbase64库(用C实现的Lua库):http://www.tecgraf.puc-rio.br/~lhf/ftp/lua/#lbase64
LuaSocket的base64库(用C实现的Lua库): http://www.cs.princeton.edu/~diego/professional/luasocket/mime.html#b64
base64的wiki:http://lua-users.org/wiki/BaseSixtyFour

最后修改:2020 年 05 月 12 日 11 : 05 AM
如果觉得我的文章对你有用,请随意赞赏