目录
- 锟拷码和口字码
- 古文码与问句码
- 符号码和拼音码
- 总结
锟拷码和口字码
说到乱码问题就不得不提到锟斤拷,这算是非常常见的一种乱码形式,那么它到底是经过何种错误操作产生的呢?下面我们一步步探究。
看一个基本示例:
"��".encode("u8").decode("gbk")
'锟斤拷'
我们将�字符以UTF-8编码后,以GBK编码解码就可以得到 锟斤拷 的乱码。
那么为什么 锟斤拷 为什么如此常见呢?这是因为大部分编程语言在使用UNICODE系列的编码去解码时,会将不识别的字节编码为0xFFFD(65533)即�字符表示未知字符进行占位:
"\uFFFD"
'�'
注意:UNICODE系列包括UTF-8、UTF-16、UTF-32编码,一般UNICODE编码指UTF-16编码。在python中unicode_escape编码表示UNICODE编码的的转义形式:
"\uFFFD".encode("unicode_escape").decode()
'\\ufffd'
对于Python,默认情况下解码碰到未知字符时会直接抛出异常,但是如果设置errors参数为replace时,则会将未知字符解码为�占位。
将汉字用GBK编码:
"小小明".encode("gbk")
b'\xd0\xa1\xd0\xa1\xc3\xf7'
将上述编码结果用UTF-8编码解码,并设置为替换模式:
"小小明".encode("gbk").decode("u8", "replace")
'СС��'
0xd0a1被解码成С,但是0xc3和0xf7无法被UTF-8编码识别,只能用占位符�替换,于是就得到了上面的结果。
此时我们再编码并解码:
"小小明".encode("gbk").decode("u8", "replace") \ .encode("u8").decode("gbk", "replace")
'小小锟斤拷'
这是因为�被编码成了0xEFBFBD
"��".encode("u8")
b'\xef\xbf\xbd\xef\xbf\xbd'
而0xEFBFBDEFBFBD被GBK解码时,正好就是锟(0xEFBF),斤(0xBDEF),拷(0xBFBD)。
上述以�为主的乱码字符就是口字码,原因是以UTF-8编码读取了GBK编码的中文。
而锟拷体则是大部分都是锟斤拷的全中文字符,原因是用GBK编码读取了UTF-8编码的口字码中文。
古文码与问句码
问句码产生的核心原因在于GBK对于无法编码的字符会使用?填充:
"�