编码: 一个隐藏了30多年的bug,Windows含蓄说过某通不行?( 三 )


与UTF-8映射关系
按照上面的规则计算下”桔子code”的UTF-8编码,首先查到“桔子code”的编码:
“桔子code”的和UTF-8编码
可以看到“code”这4个字符的编码范围在第1段 0000~ 007F范围内,右侧橙色框中表示的编码和左侧橙色框的UTF-8编码是一样的,和ASCII编码也保持一致 。“桔”的编码为,“子”的编码为,下面来计算下是怎么对应到UTF-8编码的 。首先找到”桔”的编码值落在第三行,将转换为二进制表示,然后按照第三行范围对应右侧的方式进行切割,首先找到最右侧的6个bit:,再往左找6个bit:,然后还剩下左边的4个bit:0110 。将这3段二进制数值从右往左依次填入,就可以得到0b10,换算成16进制,得到的结果为,换算的结果和网页上查到的UTF-8编码值是一样的 。”子”的计算过程是一样的 。
编码和UTF-8编码转换过程
用同样的方法可以计算出“联通”2个字符的UTF-8编码值,再回来看保存了“联通”2个字符的文本文件时,其正式编码值 和 前面多出了 EF,BB,BF 3个字节的内容,这3个字节用来表示这个文本文件用的是UTF-8编码方式,和用的2种编码一样也是一种BOM(字节序) 。
桔子菌长长地叹了一口气:终于把背景介绍的差不多了,现在要来填最开始的那个坑了 。
由于历史的原因,文本文件出现的时候并没有像图片文件那样在文件内部约定其编码方式,只是后来新出现了其他的编码方式之后才开始有些约定,比如的大端模式和小端模式,分别在文件头用了FEFF或者FFFE表示这是一种的编码方式,而带BOM的UTF-8编码方式在文件中则用表示是一个带BOM的UTF-8编码,但是这仅仅是带BOM的,还有些文件是可以不带BOM的UTF-8编码方式 。当文本程序打开一个文本文件时,如果没有在文件内部指明采用哪种编码方式,它就会采取“猜测”的方式去判断可能使用的编码方式,在“猜测”的时候就有可能出错了 。
我们来看看可能的情况,只能说是可能,因为没有拿到程序的源码抓bug那是耍流氓 。前面查到“联通”2个字的编码为C1AA,CDA8,转换成二进制就是,,恰好能被误解为2字节的UTF-8编码:
如果当成2字节UTF-8,提取其中有效bit位构成的编码为:,,按道理前者对应的是字母”j”,但是记事本程序可能并不能理解2字节宽度的,所以显示的是乱码,而后者查到的字符是下图这样的,可能操作系统中没有相应的字体也会显示出乱码来:
桔子菌讲得口水都干了,现在也差不多到了总结的时候了:今天讲了这么多,从一个记事本程序的bug聊到了ASCII,,,UTF-8,这一大堆概念中有些是字符集、有些是编码方法,有些是国标、有些是ISO标准 。比如ASCII即是字符集,自身也包含了编码方法,所以有时说ASCII字符集,有时候说ASCII编码,其实是一个意思,是字符集,而UTF-8则是的编码方法 。关于不能正常显示文件内容的问题,就是因为存在各种编码标准,而文本文件又没有约定内部某个字节表示其采用哪种编码方式,所以应用程序就只好去猜测文件用哪种编码方式,就会出现猜错的情况 。橙子妹听完似有所悟,表示对字符编码有了个大概的了解,另外对桔子菌这么能扯表达了滔滔不绝的敬仰之情 。
橙子妹回到电脑前也新建了个联通的txt文件玩一下,但是发现并没有出现不能正常显示的问题 。桔子菌在一旁提醒道:这可是30年的老bug了,微软良心发现”终于做出这个决定”,在30年之后还是把这个bug修复了,所以在 1909之后的版本不存在这个问题了 。
往期精彩:
PATH变量、命令行、搜索路径
好冷的–源文件编码