如何使用Base126编码存储任意二进制数据?
Base126编码:二进制数据转1-127字节的高效方案
核心结论
你的思路完全正确——这就是Base126编码的典型场景。相比你之前的6位/字节方案(等效Base64),Base126每字节能承载约6.97位数据(log2(126)≈6.97),传输相同二进制数据时体积更小,完全适配《Dual Universe》的传输限制:无空字符、UTF-8单字节(最高位为0)。
实现核心步骤
1. 二进制数据转大整数
把输入的二进制字节数组当作一个无符号大整数处理。比如字节数组[0x12, 0x34]对应整数0x1234 = 4660。大部分语言都支持大整数操作(Python的int、Java的BigInteger),如果语言不支持(比如Lua),可以用数组模拟大整数的存储与运算。
2. 大整数转126进制序列
通过反复对126取余得到每一位的0-125值,再加1映射到1-126的编码字节。如果127也允许使用,可以把126映射为127,刚好覆盖1-127的全范围。
伪代码示例:
function encode(data): encoded = [] # 将字节数组转为大整数(以大端为例) num = bytes_to_bigint(data) while num > 0: remainder = num % 126 encoded_byte = remainder + 1 # 0→1, 125→126 encoded.append(encoded_byte) num = num // 126 # 取余得到的是低位到高位,反转后得到正确顺序 encoded.reverse() # 处理空输入:用1表示空数据 if not encoded: encoded = [1] return encoded
3. 解码反向操作
把编码后的1-127字节减1得到0-126的126进制序列,再将其转回大整数,最后拆分为二进制字节数组即可。
4. 边界处理
- 空数据:用固定值(如1)标记,避免输出空数组。
- 填充:若需要固定长度输出,可用127作为填充位,解码时忽略。
- 字节序:编码和解码时保持字节数组的顺序(大端/小端)一致。
借鉴Base85的优化技巧
Base85通过批量处理4字节二进制数据转5字节编码提升效率,你可以复用这个思路:
- 每次取
n字节二进制数据(比如3字节=24位),计算对应数值后转成m字节126进制编码(m = ceil(24 / 6.97) ≈ 4)。 - 批量处理比逐字节操作大整数的运算效率更高,尤其适合大体积数据。
语言实现建议
- Python:直接用原生
int处理大整数,无需额外库,代码极简。 - Lua:由于Lua的number是双精度浮点数,超过2^53会丢精度,需用数组模拟大整数的取余、除法运算,或引入第三方大整数库。
- Java/C#:用内置
BigInteger类快速实现进制转换。
关键注意点
- 确认游戏对127的支持:如果127也被限制,就只使用1-126,严格按126进制映射。
- 编码后必须确保所有字节值在1-127之间,避免触发UTF-8多字节识别逻辑。
内容的提问来源于stack exchange,提问作者Statement
相关产品推荐
相关产品推荐

