锟斤拷是如何炼成的?

· · 科技·工程

upd:感谢 uid=856004 的指正。

看到有大神写了一篇关于字符编码的文章。于是打算顺带讲讲信息高速公路修到中国的一些往事。本文参考了这个视频,推荐大家去看看。

大家大概都知道最早的字符集是 ASCII,它的每个字只占半个字节,这很明显是因为英文字母太少了。当信息技术被引入中国时,由于汉字实在是太多了,于是大家被迫开发新的编码,这时候就整理出了一个叫做 GB2312 的字符集,里面涵盖了 6763 个常用的汉字(很多字体的名字后面带了一个 GB2312,就是指它只支持这些字)。

但这显然是远远不够的,很多姓名中的常见字都无法打出(据说导致很多人办身份证时被迫改名),于是微软在 GB2312 字符集的基础上搞出了一个叫做 GBK 的字符编码,它的每个字都占两个字节,于是一切都看着十分和平美好(虽然其他欧洲国家自己搞的扩展 ASCII,即 EASCII 还有点冲突,但和中国其实没有太大关系)。

直到 Unicode 杀死比赛。号称万国码的 Unicode 那兼容性可是太强了,于是许多人放弃了 GBK 去使用 Unicode。可 Unicode 是变长的,而且搞的还是中日韩越统一表意文字,和 GBK 压根兼容不了。虽然国标都开始用 UTF-8 了,然而各处还是遗留着各种老设备老软件,于是锟斤拷就诞生了。

上面的只是一些历史铺垫,接下来是复现指南。

用 Unicode 打开一个 GBK 编码的文段,肯定是不能正常显示的,所以 Unicode 会用一个替代字符�(U+FFFD,0x EF BF BD)来代替。而这时如果按下 Ctrl+S,再用 GBK 打开,我们会发现,0xEF BF,0xBD EF,0xBF BD 刚好对应的是“锟斤拷”三个字。两个�就意味着一个锟斤拷,而一堆�就意味着一堆锟斤拷。

“烫烫烫”和“屯屯屯”则和 vscode 有关,vscode 在 Debug 模式下会把未初始化的栈内存弄成 0xCC,把堆的弄成 0xCD,分别对应“烫烫烫”和“屯屯屯”。微软你坏事做尽!

你甚至可以利用这些特性搞一个很神秘的赛博魔术:在一台系统比较旧(比如说机房电脑,Win7 可以 Win8 没试过)的电脑上打开记事本,输入“联通”两字,保存,退出再打开,你会发现这两个字变成了乱码。这是因为“联通”的 GBK 编码很像 UTF-8 的,因此用默认 GBK 保存的编码会被当做 UTF-8 的打开,于是乱码出现了。可以用来和同学打赌换一瓶冰红茶,好玩!微软你好事做尽!