实际上锟斤拷/烫烫烫/屯屯屯/锘锘锘都是字符集转换之间的问题,一些特定用途的字节在另一种字符集编码表现为这些特殊字符。
接下来,让我们一一看看它们的来历。
锟斤拷
起源于 GBK 字符集于 Unicode 字符集之间的转换。众所周知,Unicode 是现在最为通用的编码方式之一,它与其它一些老编码体系进行转换时,一定存在一些 Unicode 无法表示的字(因为 Unicode 设计的时候并未完全兼容所有的编码体系,而且也没有必要),所以 Unicode 官方使用了一个占位符来表示这些无法表示的文字,即:U+FFFD (REPLACEMENT CHARATER),这样我们考察 U+FFFD 的 UTF-8 编码表示,是"0xef0xbf0xbd",如果重复多次,如"0xef0xbf0xbd0xef0xbf0xbd",然后在 GBK/CP936/GB2312/GB18030 字符集中解码的话,一个汉字两个字节,最终结果就是锟斤拷——锟(0xEFBF),斤(0xBDEF),拷(0xBFBD)。
#!/usr/bin/env python# -*- coding=utf8 -*-
"""
# File Name : kunjinkao.py
# Author : SangYu
# Email : sangyu.code@gmail.com
# Created Time : 2022年08月02日 星期二 21时53分16秒
# Description :
"""
if __name__ == "__main__":
for i in u'\uFFFD'.encode('utf-8'):
print("%x" % ord(i)),
print ""
print((u'\uFFFD'.encode('utf-8')*2).decode('gbk'))
for i in u'锟斤拷'.encode('gbk'):
print("%x" % ord(i)),
pass
执行结果:
烫烫烫与屯屯屯
Windows 平台中,MicroSoft 的 VC 编译器为了 debug 内存问题,在用户开启 Debug 模式时,会将未初始化的栈内存全部使用 0xcc 进行填充,对于未初始化的堆内存全部使用 0xcd 进行填充,同样的道理,我们查看这个值得 GBK 码表示如下:
[hex(ord(i)) for i in u'烫烫烫'.encode('gbk')][hex(ord(i)) for i in u'屯屯屯'.encode('gbk')]测试结果:
锘锘锘
UTF 编码方案中有标识编码的标准标记,如 UTF-16 中是 FF FE,当我们在编写网页时使用记事本进行编辑,此时使用的是 GBK 编码,那么转换过来就会增加一个 Unicode 保留字符 U+FEFF,同样地,如果这个字符头被表示为 UTF-8 编码后,就是"0xEF0xBB0xBF",当转换为 GBK 编码后,就会是如下的字符:
- 锘 EFBB
- 匡 BFEF
- 豢 BBBF
测试结果: