Python 记事本写‘联通’乱码的原因

微软本着顾客就是上帝的原则,就把卖给中国人的有系统默认使用GBK编码,卖给韩国人的系统默认使用EUC-KR编码,其他国家也是如此。

但是为了避免广大消费者误会卖给我们的系统功能有差异,微软就把统一默认编码都显示成ANSI。

在我们的电脑里面,ANSI也就是我们的GBK系列的编码,当我们用记事本另存的时候在下面就可以看到。

关于这个记事本,有个很注明的奇怪现象,当你在windows的记事本里新建一个文件,输入联通这两个字后,保存,关闭。

然后再次打开,你会发现这两个字变成了乱码。

有人说这就是联通之所以干不过移动的原因,其实这是因为GBK编码与UTF-8编码产生了编码冲撞的原因。

Unicode         UTF-8
0000 - 007F     0XXXXXXX
0080 - 07FF     110XXXXX 10XXXXXX
0800 - FFFF     1110XXXX 10XXXXXX 10XXXXXX

上面这一段就是从Unicode到UTF-8的转换规则。当然是按十六进制分的。

Unicode编码中从0000到007F,对应UTF-8中的二进制编码,就是以0开头,占用一个字节。

Unicode编码中从0080到07FF这段编码对应的是UTF-8中的110开头的一个字节,10开头的一个字节,两个字节

0800到FFFF这段编码,对应的是UTF-8中的1110开头的1个字节,10开头的一个字节,还有一个10开头的一个字节,这里要用三个字节。

列入仙这个字,Unicode编码是4ED9,4ED9在0800和FFFF之间,所以需要这个三个字节的模板。

4ED9转换成二进制是0100 1110 1101 1001 ,把这个比特流按三字节模板拆,就变成了这样,依次替换模板中的X,得到1110-0100 10-111011 10-011001。

再转成16进制,就变成了E4BB99。

 仙---->4ED9---->1110-0100 10-111011 10-011001
 1110-0100 10-111011 10-011001--->E4BB99

这其实就是UTF-8的编码,而当你新建一个文本文件时,记事本编码默认是ANSI,前面我们说过ANSI在我们电脑里其实就是GB系列编码方式。

在这种编码下,联通的内码是:C1AA CDA8.这也是16进制的。

前面我们学进制转换的时候知道,每四位二进制可以转换成1位十六进制,也就是说每两位十六进制就是一个字节。

C1就是第一个字节,转成二进制就是110 0001。

AA是第二个字节,转成二进制就是1010 1010。

CD是第三个字节,转成二进制就是1100 1101。

A8是第四个字节,转成二进制是1010 1000。

 C1--->1100 0001
AA--->1010 1010 
CD--->1100 1101
A8--->1010 1000

我们来看第三四个字节的开头部分,都是110和10,正好与UTF-8规则里的两字节模板是一致的。

于是再次打开这个文件的时候,及时本会自动识别编码方式,它就误认为这是一个UTF-8编码的文件,会把第一个字节的110和第二个字节的10去掉。于是就得到了00001 101010。

再把各位对齐,补上前面的0,就得到了0000 0000 0110 1010,这个二进制就转成十六进制就变成了006A。

Unicode的006A也就是小写的字母j,而之后的两个字节用UTF-8解码之后是0368,这个字符什么也不是。

0000 0000 0110 1010--->006A--->j
0000 0011 0110 1000--->0368--->不存在

这就是联通两个字的文件没有办法在记事本里正常显示的原因。如果你在联通后面输入几个字,其他的字的编码不见得有恰好是110和10开始的字节,这样再次打开时记事本就不会坚持这是一个UTF-8编码的文件。

而会用ANSI的方式解读,这是乱码就不会出现了。

未经允许不得转载:445IT之家 » Python 记事本写‘联通’乱码的原因

赞 (0) 打赏

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

微信扫一扫打赏