← 所有文章

0x9a:十六进制背后的字符隐喻

0x9a 是十进制的 154,也是在 Windows-1252 中表示 š 的一个字节。这个小小的编码关系,成了域名与 Logo 的起点。

本文目录

0x9a 是一个十六进制数,换成十进制是 154。但如果把它当作一个字节,再指定 Windows-1252 编码,就会得到另一个答案:š。

raw = bytes([0x9A])
text = raw.decode('cp1252')

print(int('9a', 16))
print(text)
print(f'U+{ord(text):04X}')

输出:

154
š
U+0161

这三个结果分别是数值、字符,以及字符的 Unicode 码点。它们相关,但并不是同一个概念。

一个字节,没有唯一的读法

ASCII 只定义了 0x00~0x7F 共 128 个码位,0x9A 已经超出了它的范围。所谓“扩展 ASCII”也不是一张统一的编码表,必须进一步指定实际编码。

在 Windows-1252 中,它对应 š;在 ISO-8859-1 中,同一个字节对应控制码点 U+009A;在 UTF-8 中,孤立的 0x9A 是一个不能独立组成字符的续字节。

raw = bytes([0x9A])
print(f"Latin-1:U+{ord(raw.decode('latin-1')):04X}")

try:
    raw.decode('utf-8')
except UnicodeDecodeError:
    print('UTF-8:不能独立解码')

而 š 本身用 UTF-8 保存时,占两个字节:

print('š'.encode('utf-8').hex(' '))
# c5 a1

因此,域名中的 0x9a 和 Logo 中的 š,通过一套具体编码建立联系。离开这套约定,就不能直接画等号。编码映射可查阅 Unicode 提供的 Windows-1252 映射表。

为什么选这个字符?

š 的基础是字母 s,上面加了一个 caron,也叫 háček,形状像一个小小的倒人字。它用于捷克语、斯洛伐克语等语言,常表示接近英语 sh 的声音。

选择 0x9a.com,首先因为它简短,也保留了十六进制记法带来的底层技术意味。

更私人的原因是,š 的核心字母 s,恰好也是我名字的首字母。于是一个数值、一个编码表中的字符和一点个人联系,聚到了一起,成了这个博客的名字。

从名字开始的一个小问题

这个名字也契合我想写的内容:先看到一个具体结果,再问它为什么如此。

同样的字节,怎样被读成文字?一个浮点数为什么比预期多出一点?一条汇编指令拿到的,到底是地址还是内容?这些问题都不大,却能把我们带到计算机真正工作的地方。

如果对这个字节的几种读法感兴趣,可以继续看乱码与编码。从 0x9a 到 š,就是这个博客的第一个小例子。

保持简单,保持好奇。

— 本文完 —

有不同的想法?欢迎在下方交流,或写封邮件。

继续翻阅其他笔记 ↗

交流与讨论