使用方法
- 选择“编码”把文本或字节转换为 Z85,或选择“解码”把 Z85 还原为数据。
- 处理密钥等二进制数据时,编码请把输入设为“十六进制”,解码请把输出设为“十六进制”。
- 输入、粘贴或打开文件,结果会随输入实时更新。
- 复制结果,或将结果下载为文件。
什么是 Z85?
Z85 由 ZeroMQ RFC 32 定义(这是 ZeroMQ 社区的规范,不是 IETF 的 RFC)。与其他 Base85 编码一样,它把每 4 个字节转换为 5 个字符:将每组字节按大端序读成一个 32 位整数,再从高位到低位写成 5 位 85 进制数。编码后体积增加 25%。
Z85 的特别之处在于字母表:0-9、a-z、A-Z 加上 23 个符号 .-:+=^!/*?&<>()[]{}@%$#。它没有使用单引号、双引号、反斜杠、反引号、逗号、分号、竖线、波浪号和下划线,这套字母表专为在源代码字符串中安全使用而设计,因此 Z85 编码结果可以直接放在 C、Python 或 JSON 的引号中,而不需要任何转义。
Z85 的使用场景
ZeroMQ 用 Z85 来表示 CurveZMQ 密钥。32 字节的公钥或私钥会编码成 40 个字符的 Z85 字符串,zmq_curve_keypair() 返回的就是这种形式,CURVE 安全机制的套接字选项也接受它。libzmq 还提供 zmq_z85_encode() 和 zmq_z85_decode(),pyzmq 等语言绑定中也有相同的函数。
// C(libzmq)
char text[41]; // 32 字节 -> 40 个字符 + NUL
zmq_z85_encode(text, key, 32);
# Python(pyzmq)
from zmq.utils import z85
z85.encode(bytes.fromhex('864fd26fb559f75b')) # b'HelloWorld'
最后一行是规范中给出的测试向量。
关于输入长度的说明
RFC 32 要求二进制输入的长度必须是 4 字节的整数倍,编码后的字符串长度必须是 5 的整数倍。规范没有定义填充,zmq_z85_encode() 等严格实现会拒绝其他长度。
本工具也接受其他长度,采用与 Ascii85 和 Base85 相同的规则:最后不足 4 字节的 n 个字节编码为 n + 1 个字符。这是非标准的扩展,这样得到的结果可能会被其他 Z85 解码器拒绝。如果需要兼容,请先把数据补齐到 4 字节的整数倍。CurveZMQ 密钥为 32 字节,本身就符合要求。
编码规格
| 字母表 | 0-9 a-z A-Z .-:+=^!/*?&<>()[]{}@%$# |
|---|---|
| 输出体积 | 每 4 字节输出 5 个字符(125%) |
| 填充 | 无 |
| 标准 | ZeroMQ RFC 32 |
| 区分大小写 | 是 |
编码示例
| 输入 (UTF-8) | 输出 |
|---|---|
Hello, World! | nm=QNz.92jz/PV8aP |
Base64.is | lsB}Dhz^42A@ |
你好 | <H}kFRm= |
常见问题
Z85 和 Ascii85 有什么区别?
! 到 u 的 ASCII 字符,其中包含引号和反斜杠,并有表示零字节的 z 缩写;Z85 避开了在字符串中需要转义的字符,也没有缩写。Z85 有填充吗?
没有。规范只允许长度为 4 字节整数倍的输入。本工具对其他长度会用较短的最后一组进行编码,这不属于标准内容。
Z85 可以用在 JSON、XML 或 URL 中吗?
Z85 编码的 CurveZMQ 密钥有多长?
CurveZMQ 密钥为 32 字节,编码后正好是 40 个字符。如需查看原始密钥,可以在这里解码并选择十六进制输出。