32/Z85
- 状态:稳定
- 编辑:Pieter Hintjens ph@imatix.com
本文档规定了 Z85,一种将二进制数据表示为可打印文本的格式。Z85 是现有 Ascii85 编码机制 的派生,为提高可用性进行了修改,尤其适用于源代码中使用。
前言
版权所有 (c) 2013 iMatix Corporation。
本规范是自由软件;您可以根据自由软件基金会发布的 GNU 通用公共许可证(第三版或您选择的任何更高版本)的条款重新分发和/或修改它。分发本规范是希望它有用,但**没有任何担保**;不包括对适销性或特定用途适用性的默示担保。有关更多详细信息,请参阅 GNU 通用公共许可证。您应该已经随本程序收到了 GNU 通用公共许可证的副本;如果没有,请参阅 https://gnu.ac.cn/licenses。
本文档中的关键词“必须 (MUST)”、“不得 (MUST NOT)”、“要求 (REQUIRED)”、“应 (SHALL)”、“不应 (SHALL NOT)”、“应该 (SHOULD)”、“不应该 (SHOULD NOT)”、“建议 (RECOMMENDED)”、“可以 (MAY)”和“可选 (OPTIONAL)”应按照 RFC 2119 中的描述进行解释。
问题陈述
在代码和文本文件(如配置数据)中表示二进制值时,开发者必须选择一种可打印的表示形式。最简单的选择是 Base16,其中每个字节表示为两个十六进制值。
为了比 Base16 更高效,开发者可能会选择 Base64。这是一种常见的选择,但存在问题,因为它有十几种变体。它与二进制数据配合不佳,因为它处理三字节块,而大多数二进制数据按 4 或 8 字节分块。因此,Base64 实现比可能的情况更复杂,并且不一定具有互操作性。
一种更逻辑的编码是 Ascii85,它处理 4 字节块。但它不是字符串安全的,因此不能在源代码、XML、JSON 等中干净地使用。
我们理想的编码设计用于像 Ascii85 一样的 4 字节块,但对字符串安全,并消除了关于实现是否会互操作的所有歧义。因此,Z85 设计得比 Base16 更紧凑,比 Base64 更可靠,比 Ascii85 更易用。
本规范的具体目标是
- 提供最有效的文本表示形式。
- 在源代码中易于使用,当用双引号或单引号括起来时。
- 在命令行中安全传递,当用单引号括起来时。
- 易于在任何编程语言中实现。
此外,全零的二进制串应易于辨识(我们通过将零映射到 ASCII 字符 '0' 来实现这一点)。
正式规范
Z85 实现接受一个二进制帧并将其编码为可打印的 ASCII 字符串,或接受一个 ASCII 编码字符串并将其解码为二进制帧。
二进制帧的长度应能被 4 整除,无余数。字符串帧的长度应能被 5 整除,无余数。由应用程序负责确保帧和字符串在必要时进行填充。
编码和解码应使用此表示形式,对应从零到 84 的每个 base-85 值
0 - 9: 0 1 2 3 4 5 6 7 8 9
10 - 19: a b c d e f g h i j
20 - 29: k l m n o p q r s t
30 - 39: u v w x y z A B C D
40 - 49: E F G H I J K L M N
50 - 59: O P Q R S T U V W X
60 - 69: Y Z . - : + = ^ ! /
70 - 79: * ? & < > ( ) [ ] {
80 - 84: } @ % $ #
为了编码一个帧,实现应每次从二进制帧中取出四个八位字节,并将它们转换为五个可打印字符。这四个八位字节应被视为网络字节序(大端序)的无符号 32 位整数。这五个字符应从最高位到最低位(大端序)输出。
为了解码一个字符串,实现应每次从字符串中取出五个字符,并将它们转换为表示网络字节序的 32 位无符号整数的四个数据八位字节。这五个字符应分别转换为 0 到 84 的值,并从最高位到最低位通过乘以 85 进行累积。
测试用例
作为一个测试用例,一个包含这 8 个字节的帧
+------+------+------+------+------+------+------+------+
| 0x86 | 0x4F | 0xD2 | 0x6F | 0xB5 | 0x59 | 0xF7 | 0x5B |
+------+------+------+------+------+------+------+------+
应编码为以下 10 个字符
+---+---+---+---+---+---+---+---+---+---+
| H | e | l | l | o | W | o | r | l | d |
+---+---+---+---+---+---+---+---+---+---+
参考实现
C 语言的参考实现位于 RFC 仓库中:https://github.com/zeromq/rfc/blob/master/src/spec_32.c。
安全注意事项
实现必须注意用于接收编码和解码数据的缓冲区足够大。显然,精心构造的编码字符串可以创建任意的二进制序列,这使得 Z85 成为攻击设计不当的实现的一个简单途径。