一个字节,两个字符
十六进制,或 hex,是 16 进制:十六个数字,0-9 然后 A-F,其中 A 到 F 表示值 10 到 15。RFC 4648 把这种编码称为 Base16。它的决定性特性既简单又有用:一个字节始终恰好是两个十六进制字符。一个字节包含 0 到 255 的值,而两个十六进制数字恰好覆盖该范围(16 × 16 = 256)。高四位(半字节)成为第一个字符,低四位成为第二个。
于是字节 0x48 在 ASCII 中是字母 H,在 hex 中写作 48。单词 foobar 是六个字节,在 hex 中是十二个字符 666F6F626172。没有需要操心的填充或块对齐:每个字节独立地对应自己的一对字符。
为什么 hex 是原始字节的默认选择
Hex 是常见编码中密度最低的,因为它把输入的大小精确地翻倍,所以在大小重要时很少用它来传输数据。它的价值在于对检查字节的人的可读性。由于每个字节都是一个自包含的对,你可以把一个 hex 字符串与它所表示的数据对齐,逐位置读取,这正是十六进制转储所做的:左边是 hex 形式的字节,右边是它们的可打印字符。
这种直接的映射就是 hex 成为本质上是字节值的事物的通用记法的原因:打印为 64 个十六进制字符(32 字节)的 哈希、一个 MAC 地址、像 #1A2B3C 这样的 RGB 颜色、调试器中的一个内存地址,或一个加密密钥的字节。在每种情况下你都不是想节省空间,你是想读取或比较确切的字节值,而 hex 让这件事变得简单。
大小写与有效性
Hex 大小写不敏感:ff、FF 和 Ff 都表示同一个字节,255。按惯例输出是大写的,但解码器两者都接受。唯一的结构规则是 hex 字符串必须有偶数个数字,因为每个字节都需要一个完整的对。像 ABC 这样奇数长度的字符串是格式错误的:剩下一个没有配对的半字节。而 0-9 和 A-F 之外的任何字符都根本不是 hex。
它如何相比
RFC 4648 的三种编码以密度换取字母表大小。Base64 最紧凑,每三个字节四个字符,但使用一个带 + 和 / 的大型、大小写敏感的字母表。Base32 居中,每五个字节八个字符,字母表更小、大小写不敏感且无歧义。Hex 最大,每字节两个字符,但最易读,拥有所有之中最清晰的字节边界。当人需要看到字节时你求助于 hex,当机器需要搬运它们时你求助于 Base64。
试一试
在 codec 工具中选择 Hex,把文本转换为它的十六进制字节或把一个 hex 字符串解码回文本,全部在你的浏览器中完成。它忽略空白,接受大写或小写,并标记出二进制而非可读文本的结果。