概述
光荣的游戏《三国志曹操传》相信很多人都玩过。当年因为乱码,导致很多人没有办法游玩正确的简体中文版,而是玩的全程不知所云的乱码版。其中,曹操就是大名鼎鼎的“变巨”。“瓣в变巨肚”其实就是“三国志曹操传”的乱码版本。
闲话不多说了。今天我想和大家分享一下,怎样用短短几行 Python 代码重现上述的编码错误。
Python 实现及原理
起初,这款游戏被台湾引进,并翻译成了繁体中文版。当时还没有普及 Unicode,所以各地都有自己的一套编码字符集。台湾使用的是 Big5,而大陆当时使用的普遍是 GB2312、GBK 等。所以,我们只需要把正确的内容根据 Big5 进行编码,然后再用 GBK 进行解码,就能得到如标题那样的乱码了。
import codecs
word = '曹操'
byte = codecs.encode(word, 'big5')
res = codecs.decode(byte, 'gbk')
print(res)
这样,我们就得到了“变巨”。那是不是这样就结束了?其实并没有。比如我们还可以试试“三國志曹操傳”。注意这里用的是繁体。我们可不希望用 Big5 编码简体字,毕竟台湾用的可不是简体中文。
结果居然报错了:
UnicodeDecodeError: 'gbk' codec can't decode byte 0xa4 in position 0: illegal multibyte sequence
这是因为,Big5 和 GBK 所涵盖的二进制编码有各自“专属”,也就是不属于二者交集的部分。上述的 0xa4
就是其中之一。遇到这个情况,GBK 无法识别,于是就报错了。
那么怎么解决呢?其实也很简单,只需要给 decode()
加一个忽略报错即可:
res = codecs.decode(byte, 'gbk', 'ignore')
这个 ignore
的作用就是忽略解码过程中遇到的无法识别的编码。其他可选的还有 strict
等。详见
这样,我们就可以“正确”地得到结果了:
T瓣в变巨肚
为什么开头会有一个“T”?其实开头那个是一个无法被 GBK 识别的字节。在比较旧的操作系统上会显示为“?”,或者干脆空白。
其实仔细看的话,当年的标题栏确实开头是有一个空白的。我们换一个老一点的控制台,也是可以看到相同的效果的:
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。