科普

Base85 编码详解:比 Base64 更紧凑的二进制文本编码方案

全面了解 Base85(Ascii85)编码的工作原理、85 个字符的字母表、编解码算法、z 零压缩与 <~ ~> 分隔符,以及它在 PostScript、PDF、Git 等领域的广泛应用。

什么是 Base85?

Base85 是一种高效的二进制到文本编码方案,使用 85 个可打印 ASCII 字符来表示任意二进制数据。它最广为人知的变体是 Ascii85,由 Paul E. Rutter 于 1985 年为 btoa 工具开发,后被 Adobe 公司采纳并用于 PostScript 和 PDF 文件格式中,因此也常被称为 Adobe Ascii85

Base85 的核心优势在于它比 Base64 拥有更高的编码效率——将 4 字节的二进制数据编码为 5 个字符,膨胀率仅为 25%,而 Base64 的膨胀率为 33.3%。这意味着在同样的数据量下,Base85 编码后的输出更短,在带宽和存储敏感的场景中具有明显优势。

在线工具推荐:需要进行 Base85 编码或解码?试试我们的在线 Base85 编解码工具,支持文本和十六进制输入、<~ ~> 分隔符、z 零压缩等多种选项。

Base85 字符表

Ascii85 使用从 ASCII 码 33(!)到 117(u)的连续 85 个可打印字符作为编码字母表:

!"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstu

每个字符对应的索引值为其 ASCII 码减去 33:

字符ASCII 码索引值
!330
"341
#352
s11582
t11683
u11784

设计理念:选择 ASCII 33-117 的范围是为了避免使用空格(32)和 DEL(127)等不可见/控制字符,同时利用尽可能多的可打印字符来最大化编码效率。

Base85 的工作原理

编码过程(4 字节 → 5 字符)

Base85 编码以 4 字节(32 位) 为一组进行处理:

  1. 读取 4 字节:将连续 4 个字节视为一个 32 位无符号整数(大端序)
  2. 进制转换:将该整数反复除以 85,取余数
  3. 字符映射:将每个余数加上 33 得到对应的 ASCII 字符
  4. 输出 5 字符:4 字节产生 5 个编码字符

数学基础:4 字节可表示的最大值为 2³² − 1 = 4,294,967,295,而 85⁵ = 4,437,053,125 > 4,294,967,295,所以 5 个 Base85 字符足以表示 4 个字节。

示例:编码字符串 “Man “(包含尾部空格)

字节:  0x4D  0x61  0x6E  0x20
整数值:1298230816(十进制)

1298230816 ÷ 85 = 15273303  余 61  → chr(61+33) = '^'
15273303   ÷ 85 = 179685    余 78  → chr(78+33) = 'o'
179685     ÷ 85 = 2113      余 80  → chr(80+33) = 'q'
2113       ÷ 85 = 24        余 73  → chr(73+33) = 'j'
24         ÷ 85 = 0         余 24  → chr(24+33) = '9'

逆序排列:9jqo^

尾部填充处理

当输入数据的字节数不是 4 的倍数时,需要在末尾补零字节凑齐 4 字节进行编码,然后丢弃多余的编码字符:

剩余字节数补零数编码字符数输出字符数
1352
2253
3154

解码时采用对称的策略:用 u(索引 84)填充至 5 字符,解码后丢弃多余字节。

解码过程(5 字符 → 4 字节)

解码是编码的逆操作:

  1. 读取 5 字符:将 5 个编码字符的索引值按 85 进制计算
  2. 还原整数:value = c₀ × 85⁴ + c₁ × 85³ + c₂ × 85² + c₃ × 85¹ + c₄ × 85⁰
  3. 拆分字节:将 32 位整数拆分为 4 个字节

特殊功能

<~ ~> 分隔符

Adobe 定义的 Ascii85 格式使用 <~~> 作为编码数据的包裹标记,用于明确标识 Base85 编码区段的起止位置。这在 PostScript 和 PDF 文件中尤为重要,因为编码数据需要嵌入在其他格式的文本中。

原始数据:Hello
不带分隔符:87cURDZ
带分隔符:  <~87cURDZ~>

z 零压缩

当一个完整的 4 字节组全部为零(即整数值为 0)时,Ascii85 可以用单个字符 z 来代替原本的 5 个编码字符 !!!!!。这种零压缩在处理包含大量零字节的数据(如图像的空白区域)时,能显著减小编码后的体积。

4 个零字节(00 00 00 00):
  标准编码:!!!!!(5 个字符)
  零压缩:  z(1 个字符)

注意z 压缩仅适用于完整的 4 字节组。对于尾部不足 4 字节的情况,不能使用零压缩。

空白字符处理

在实际应用中,Base85 编码的数据经常被格式化为多行显示(例如在 PostScript 文件中每行限制 80 个字符)。解码器通常会忽略编码数据中的空白字符(空格、制表符、换行符等),以正确处理换行和格式化。

编码效率对比

编码方案输入 : 输出膨胀率字符集大小
Base854 : 525%85
Base643 : 433.3%64
Base62大整数运算~37%62
Base58大整数运算~37%58
Base325 : 860%32
Base16 (Hex)1 : 2100%16

Base85 的主要变体

1. Ascii85(Adobe 变体)

  • 字符集:ASCII 33-117(!u
  • 分隔符<~ ~>
  • 零压缩:支持 z 字符
  • 用途:PostScript、PDF 文件格式
  • 状态:最广泛使用的变体,也是我们工具实现的版本

2. Z85(ZeroMQ 变体)

  • 字符集0-9a-zA-Z.-:+=^!/*?&<>()[]{}@%$#(重新排列的 85 个字符)
  • 分隔符:无
  • 零压缩:不支持
  • 用途:ZeroMQ 消息传输、网络协议

3. RFC 1924 变体(IPv6)

  • 字符集0-9A-Za-z!#$%&()*+-;<=>?@^_{|}~
  • 用途:提出用于 IPv6 地址的紧凑表示(愚人节 RFC,未广泛实施)
  • 特点:128 位 IPv6 地址编码为 20 个字符

4. btoa 原始格式

  • 字符集:与 Ascii85 相同
  • 分隔符xbtoa Beginxbtoa End
  • 特点:包含校验信息,是 Ascii85 的前身

常见应用场景

1. PostScript 和 PDF

Base85 最重要的应用是在 Adobe 的 PostScript 和 PDF 文件格式中。这些格式需要将二进制数据(如图像、字体、嵌入文件)编码为文本形式,Base85 比 Base16 和 Base64 都更紧凑,能有效减小文件体积。

2. Git 二进制补丁

Git 版本控制系统在生成二进制文件的补丁(binary diff/patch)时使用 Base85 编码。当执行 git diff 对二进制文件产生差异时,Git 使用 Base85 将差异数据编码为文本格式。

3. 数据序列化与传输

在需要通过纯文本通道传输二进制数据的场景中(如 JSON 嵌入、XML CDATA),Base85 比 Base64 节省约 6% 的空间。

4. 网络协议

ZeroMQ 使用 Z85 变体在消息中嵌入二进制数据,确保编码后的字符串在各种编程语言和传输协议中都能安全传递。

5. 嵌入式系统

在存储和带宽受限的嵌入式环境中,Base85 的 25% 膨胀率相比 Base64 的 33.3% 可以节省宝贵的存储空间和传输带宽。

Base85 与其他编码方案的比较

特性Base85Base64Base62Base58Base91
字符集大小8564625891
膨胀率25%33.3%~37%~37%~14-23%
编码单位4→53→4大整数大整数位流
包含特殊符号
URL 安全❌ 需变体
零压缩
标准化Adobe 标准RFC 4648
主要用途PS/PDF/Git通用传输短链接/ID加密货币极致紧凑

实现注意事项

  1. 整数溢出:4 字节编码时涉及的最大值为 85⁵ − 1 = 4,437,053,124,在 JavaScript 的安全整数范围内,但在 C/C++ 等语言中需注意使用无符号 32 位整数。

  2. z 字符位置z 只能替代完整的 4 字节零组,不能出现在 5 字符组的中间。解码器在遇到 z 时应检查当前组是否为空。

  3. 非法字符检测:编码后的字符应在 ASCII 33-117 范围内(加上可选的 z)。解码器需要验证字符合法性。

  4. 分隔符处理:解码时需正确识别和去除 <~ ~> 分隔符,同时支持有无分隔符的两种输入格式。

  5. 大文件处理:建议采用流式处理(以 4 字节为单位逐组编码),避免将整个文件加载到内存中。

Base85 的优缺点

优点

  • 编码效率高:25% 膨胀率,在常用编码中仅次于 Base91
  • 零压缩:对含大量零字节的数据可进一步压缩
  • 工业标准:被 Adobe PostScript/PDF 和 Git 等广泛采用
  • 固定比率:4:5 的固定编码比率使得输出长度易于预测
  • 分隔符<~ ~> 提供了清晰的边界标记

缺点

  • 包含特殊字符:编码结果包含需要转义的字符
  • 非 URL 安全:包含 URL 特殊字符,不能直接用于 URL
  • 大小写敏感:在不区分大小写的环境中可能出问题
  • 实现复杂度:比 Base64(纯位操作)更复杂,需要除法运算
  • 变体众多:Ascii85、Z85、btoa 等变体的字符集不同,互不兼容

安全性考虑

  1. Base85 不是加密:与所有编码方案一样,Base85 只是数据表示方式,不提供保密性。敏感数据必须先加密再编码。

  2. 注入风险:Base85 编码结果包含 <>" 等特殊字符,直接嵌入 HTML、XML 或 SQL 中可能导致注入攻击,应进行适当转义。

  3. 数据完整性:标准 Ascii85 不包含内置校验和。如需确保数据完整性,应在应用层添加 CRC 或哈希校验。

如何选择合适的编码?

  • 需要最高编码效率且允许特殊字符:选择 Base85Base91
  • 需要通用兼容性和广泛支持:选择 Base64(RFC 标准)
  • 需要 URL 安全:选择 Base62Base58
  • 需要嵌入 PostScript/PDF:选择 Base85 (Ascii85)
  • 需要人工输入不易出错:选择 Base58(无混淆字符)

总结

Base85(Ascii85)是一种高效、成熟的二进制文本编码方案。它以 25% 的低膨胀率在编码效率上显著优于 Base64,同时提供了 z 零压缩和 <~ ~> 分隔符等实用特性。从 Adobe PostScript/PDF 到 Git 二进制补丁,Base85 在需要紧凑文本表示的场景中发挥着重要作用。

如果你正在处理 PDF 生成、Git 补丁解析,或任何需要高效二进制文本编码的场景,Base85 都是一个值得优先考虑的方案。赶快使用我们的 Base85 编解码工具 来亲身体验吧!