lua版本base64加密和解密

特别注意
Base64 主要不是加密,它主要的用途是把一些二进制数转成普通字符用于网络传输。由于一些二进制字符在传输协议中属于控制字符,不能直接传送需要转换一下就可以了
原理
将文件读入内存,由于读入内存的文件本质上是一个字节类型数组bufferA,新建一个bufferB,对数组A中连续的每三个字节值取出,将其扩充成四个字节,不够的高位补0,对于最后组不成三个字节的处理,少一个就补一个=,最多补两个==;
举例:加密“ace”,

ace转化为二进制为:‭01100001‬ ‭01100011‬ ‭01100101‬

转化为base64的四字节六位:011000 01‬‭0110 0011‬01 100101‬

那因为计算机是一字节八位的存数,所以高位补00后变为:00011000 0001‬‭0110 000011‬01 00100101‬

转化为十进制:24 22 13 37

查Base64对照表(默认版本RFC2045):
在这里插入图片描述我们得到最终结果:YWNl
我们观察这个对照表,大小写的字母26*2 加上10个数字 加上两个特殊符号 + / 一共64个字符,因为Base64有效位只有六位,所以最大能表示的字符就为2的6次方64;
分享一个lua版本的base64源码:

local Base64 = {}
local string = string
Base64.__code = {
            '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', '+', '/',
        };
Base64.__decode = {}
for k,v in pairs(Base64.__code) do
    Base64.__decode[string.byte(v,1)] = k - 1
end
function Base64.encode(text)
    local len = string.len(text)
    local left = len % 3
    len = len - left
    local res = {}
    local index  = 1
    for i = 1, len, 3 do
        local a = string.byte(text, i )
        local b = string.byte(text, i + 1)
        local c = string.byte(text, i + 2)
        -- num = a<<16 + b<<8 + c
        local num = a * 65536 + b * 256 + c 
        for j = 1, 4 do
            --tmp = num >> ((4 -j) * 6)
            local tmp = math.floor(num / (2 ^ ((4-j) * 6)))
            --curPos = tmp&0x3f
            local curPos = tmp % 64 + 1
            res[index] = Base64.__code[curPos]
            index = index + 1
        end
    end

    if left == 1 then
        Base64.__left1(res, index, text, len)
    elseif left == 2 then
        Base64.__left2(res, index, text, len)        
    end
    return table.concat(res)
end

function Base64.__left2(res, index, text, len)
    local num1 = string.byte(text, len + 1)
    num1 = num1 * 1024 --lshift 10 
    local num2 = string.byte(text, len + 2)
    num2 = num2 * 4 --lshift 2 
    local num = num1 + num2
   
    local tmp1 = math.floor(num / 4096) --rShift 12
    local curPos = tmp1 % 64 + 1
    res[index] = Base64.__code[curPos]
    local tmp2 = math.floor(num / 64)
    curPos = tmp2 % 64 + 1
    res[index + 1] = Base64.__code[curPos]

    curPos = num % 64 + 1
    res[index + 2] = Base64.__code[curPos]
    
    res[index + 3] = "=" 
end

function Base64.__left1(res, index,text, len)
    local num = string.byte(text, len + 1)
    num = num * 16 
    
    tmp = math.floor(num / 64)
    local curPos = tmp % 64 + 1
    res[index ] = Base64.__code[curPos]
    
    curPos = num % 64 + 1
    res[index + 1] = Base64.__code[curPos]
    
    res[index + 2] = "=" 
    res[index + 3] = "=" 
end

function Base64.decode(text)
    local len = string.len(text)
    local left = 0 
    if string.sub(text, len - 1) == "==" then
        left = 2 
        len = len - 4
    elseif string.sub(text, len) == "=" then
        left = 1
        len = len - 4
    end

    local res = {}
    local index = 1
    local decode = Base64.__decode
    for i =1, len, 4 do
        local a = decode[string.byte(text,i    )] 
        local b = decode[string.byte(text,i + 1)] 
        local c = decode[string.byte(text,i + 2)] 
        local d = decode[string.byte(text,i + 3)]

        --num = a<<18 + b<<12 + c<<6 + d
        local num = a * 262144 + b * 4096 + c * 64 + d
        
        local e = string.char(num % 256)
        num = math.floor(num / 256)
        local f = string.char(num % 256)
        num = math.floor(num / 256)
        res[index ] = string.char(num % 256)
        res[index + 1] = f
        res[index + 2] = e
        index = index + 3
    end

    if left == 1 then
        Base64.__decodeLeft1(res, index, text, len)
    elseif left == 2 then
        Base64.__decodeLeft2(res, index, text, len)
    end
    return table.concat(res)
end

function Base64.__decodeLeft1(res, index, text, len)
    local decode = Base64.__decode
    local a = decode[string.byte(text, len + 1)] 
    local b = decode[string.byte(text, len + 2)] 
    local c = decode[string.byte(text, len + 3)] 
    local num = a * 4096 + b * 64 + c
    
    local num1 = math.floor(num / 1024) % 256
    local num2 = math.floor(num / 4) % 256
    res[index] = string.char(num1)
    res[index + 1] = string.char(num2)
end

function Base64.__decodeLeft2(res, index, text, len)
    local decode = Base64.__decode
    local a = decode[string.byte(text, len + 1)] 
    local b = decode[string.byte(text, len + 2)]
    local num = a * 64 + b
    num = math.floor(num / 16)
    res[index] = string.char(num)
end
return Base64

测试代码如下:

function Base64File(sourcepath,targetpath,isEncode)
	local file = io.open(sourcepath,"rb")
	if file then
	    --print "发现文件\n"
	    local files = file:read("*a");
	    local result;
	    if  isEncode == true then
	        result = require("./Base64").encode(files);
	    else
            result = require("./Base64").decode(files);
        end
	    local tagetFile = io.open(targetpath, "wb")
		tagetFile:write(result);
		tagetFile:close();
	    file:close();
	else
	    print "没有找到文件"
	end
end

--例子
--Base64File("./source.jpeg","./mnp.jpeg",true)
--Base64File("./mnp.jpeg","./mn.jpeg",false)
--Base64File("./test.lua","./testLua.lua",true);
Base64File("./testLua.lua","./testLuaNew.lua",false)

最后:标准的Base64并不适合直接放在URL里传输,因为URL编码器会把标准Base64中的“/”和“+”字符变为形如“%XX”的形式,而这些“%”号在存入数据库时还需要再进行转换,因为ANSI SQL中已将“%”号用作通配符。
为解决此问题,可采用一种用于URL的改进Base64编码,它不仅在末尾去掉填充的’='号,并将标准Base64中的“+”和“/”分别改成了“-”和“_”,这样就免去了在URL编解码和数据库存储时所要作的转换

  • 1
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
A:在cocos2dx中,可以通过加密lua代码和图片资源来保护项目的安全性。下面是一些简单的步骤来加密解密lua代码和图片资源: 1. 加密Lua代码 可以使用luajit来编译Lua代码,然后使用gzip压缩和base64编码来加密Lua代码。以下是使用此方法加密Lua代码的示例代码: ``` local status, bytecodes = pcall(function() local bytecodeStream = io.popen("luajit -bg myScript.lua -") local bytecode = bytecodeStream:read("*all") bytecodeStream:close() return bytecode end) if not status then error(bytecodes) end local compressed = zlib.compress(bytecodes, 9) local cipher = mime.b64(compressed) ``` 2. 加密图片资源 可以使用图片加密工具,如TexturePacker,将图片打包成一个txp包。然后可以使用AES加密算法来加密txp包,以下是使用此方法加密图片资源的示例代码: ``` local Crypto = require "crypto" local data = cc.FileUtils:getInstance():getDataFromFile("myImage.txp") local iv = Crypto.digest("sha256", "mySecretKey", true) local key = Crypto.digest("md5", "mySecretKey", true) local encrypted = Crypto.encryptAES256(data, key, iv) cc.FileUtils:getInstance():writeDataToFile(encrypted, "myImageEncrypted") ``` 3. 解密Lua代码 可以使用base64解码和gzip解压缩函数解密加密Lua代码,然后使用loadstring函数来运行解密后的代码。以下是使用此方法解密Lua代码的示例代码: ``` local cipher = "..." local compressed = mime.unb64(cipher) local bytecodes = zlib.decompress(compressed) local f = loadstring(bytecodes) f() ``` 4. 解密图片资源 使用AES解密算法来解密加密的图片资源。以下是使用此方法解密图片资源的示例代码: ``` local Crypto = require "crypto" local encrypted = cc.FileUtils:getInstance():getDataFromFile("myImageEncrypted") local iv = Crypto.digest("sha256", "mySecretKey", true) local key = Crypto.digest("md5", "mySecretKey", true) local decrypted = Crypto.decryptAES256(encrypted, key, iv) cc.FileUtils:getInstance():writeDataToFile(decrypted, "myImage") ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值