为什么 base64 胜过 uuencode?
Base64 相较于 uuencode 的胜出,被归因于早期电子邮件和网络系统对可靠性与可移植性的要求:其 64 字符字母表被设计为能够在 ASCII、EBCDIC 以及会破坏空白字符的网关之间顺利传输,而 uuencode 和像 BinHex 这样的格式经常做不到。评论者深入讨论了 ASCII 看似古怪的布局背后的历史约束、向后兼容与性能之间的权衡,以及相关的编码变体(yEnc、URL-safe base64、quoted-printable),强调现实中的协议怪癖和标准化如何塑造了今天的二进制到文本编码。
为什么 Base64 “胜出” 了 uuencode
Base64 是为 MIME 邮件设计的,满足严格的可移植性需求。
- 它的字母表是一个子集,其中的字符在所有 ISO 646 变体和所有 EBCDIC 变体中都能被一致表示。
- uuencode 的字母表包含一些字符,无法在 EBCDIC 和其他非 ASCII 环境中可靠映射,导致在真实部署中发生损坏。
- uuencode 中的空格和其他脆弱字符经常被邮件系统弄乱,因为这些系统会规范化或改动空白字符。
Base64 提供一致的开销(约 33%),而 uuencode 会增加逐行开销,使其整体效率更低(有效效率可能降至约 60–70%)。
一旦 MIME 和 SSL/TLS 将 Base64 标准化,它就成了到处默认使用的方案;实际可用性和工具支持随后又进一步巩固了它的主导地位。
ASCII 设计、向后兼容性与性能争论
多条评论将 ASCII 的布局解释为历史约束的产物:
- 位级特性(例如通过单个位进行大小写转换、Control 键行为)。
- 需要支持 6 位设备和机械终端。
- EBCDIC 那种奇怪的布局也同样与打孔卡技术有关。
有一位参与者批评“向后兼容性”和 ASCII 的布局损害了长期效率(例如 int→hex 需要额外指令、字母表检查,以及缺少按位配对的标点)。
其他人则强烈反对:
- 认为这些性能担忧在现代 CPU 上被夸大了,在真实工作负载中几乎无关紧要。
- 指出解析器和词法分析器并不会因假想的“成对标点”编码而受益多少。
- 还提到,一旦 ASCII 已经部署,改变它在实践中几乎不可能。
还有人批评 Unicode 让原本简单的 1 字节→1 字符映射变得复杂,不过也承认它对于现实中的语言是必要的。
Base64 的设计细节与变体
关于填充(
=)的讨论:- 有人认为它没必要,因为 Base64 字符串的长度已经能编码缺少多少字节;填充被认为只是历史遗留或品味问题。
- 也有人指出,填充有助于在拼接分别编码的块时保留片段边界;如果没有填充,边界就会变得模糊。
文中还提到 Base64 的变体(URL/文件名安全、无填充),但如果编码器/解码器在字母表和填充规则上不一致,就会出现互操作性问题。
其他编码与历史背景
- 讨论了 yEnc、BinHex、BinSCII、MacBinary、StuffIt 和 XXBUG 等与特定平台相关的二进制到文本编码替代方案(Usenet、经典 Mac、MS-DOS)。
- 经典 Mac 的资源分叉/数据分叉和元数据需求推动了 BinHex 及类似包装格式的出现。
- 评论者还提到了 ascii85 的存续,以及早期网页下载、Kermit 和文件传输工具带来的各种怀旧经历。