Lua编解码函数适配Unicode问题:如何正确解码非8位二进制序列?
解决Lua字符与二进制互转的Unicode及无空格解码问题
原代码的核心问题在于按单字符对应单字节处理,但Unicode字符在Lua中以UTF-8多字节编码存储,同时无空格的二进制串缺少明确的字节分割标记。以下是修复后的实现方案:
修复后的代码
local insert, concat, format = table.insert, table.concat, string.format -- 将字符串(含Unicode)转为空格分隔的8位二进制序列 function ToBinary(str) local result = {} -- 遍历字符串的每个UTF-8字节 for i = 1, #str do local byte = str:byte(i) -- 将字节转为8位二进制(不足8位补前导0) local bin_str = format("%08d", tonumber(format("%b", byte))) insert(result, bin_str) end return concat(result, ' ') end -- 从二进制序列(含/不含空格)解码为字符串(支持Unicode) function FromBinary(str) -- 移除所有空格,统一处理有无分隔的情况 local clean_str = str:gsub('%s+', '') -- 检查二进制串长度是否为8的倍数(每个字节对应8位) assert(#clean_str % 8 == 0, 'Invalid binary sequence: length must be multiple of 8') local result = {} -- 每8位一组解码为字节 for i = 1, #clean_str, 8 do local bin_segment = clean_str:sub(i, i+7) local byte = tonumber(bin_segment, 2) assert(byte, 'Malformed binary segment: ' .. bin_segment) insert(result, string.char(byte)) end -- 拼接字节为UTF-8字符串 return concat(result) end
关键改进点
Unicode支持:
Lua字符串默认采用UTF-8编码,#str返回的是字节数而非字符数。修复后的ToBinary遍历每个UTF-8字节,将其转为标准8位二进制;FromBinary则把解码后的字节直接拼接,还原为原始UTF-8字符串,自然支持所有Unicode字符。无空格二进制处理:
先移除所有空格,再检查总长度是否为8的倍数(UTF-8每个字节固定8位),之后按每8位一组分割解码,无需依赖空格分隔符。避免精度问题:
原代码通过对数计算二进制位数存在精度误差(如小数值的浮点计算偏差),修复后直接用string.format("%b", byte)获取二进制字符串,再补前导0到8位,结果更可靠。
内容的提问来源于stack exchange,提问作者frogl8
相关产品推荐
相关产品推荐

