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

原文链接:
桔子菌:你听说过微软30多年前推出的时候,隐晦表达过联通不行移动行么?橙子妹瞟了一眼桔子菌:瞎扯,我只听葛优说过“神州行我看行” 。桔子菌有点炫耀:不可思议是吧?你看我用自带的记事本软件新建2个txt文件,在文件中分别输入“联通”和“移动”,再次打开文件看,发现保存了“移动”的文件仍然可以看到“移动”2个字,但是保存“联通”的文件就不行了,看不到了 。橙子妹稍微有点惊讶,又瞟了一眼桔子菌:你这是哪跟哪,不过我还是有点好奇这是怎么回事 。桔子菌:请听我娓娓道来 。
微软你想说某通不行可以直接点吗
在计算机的世界里,不管是内存、硬盘存储的内容都是“0”和“1”,网络上传输的数值也是“0”和“1”,CPU能处理的也是“0”和“1” 。单个bit只能表示”0″和”1″的2种数值状态,通过bit位数的增加就可以表示更多的数值 。通常用8个这样的”0″或”1″构成一个字节,这样一个字节就包含了256种数值,再进一步的2个字节就能表示65536种数值 。这些数值表达什么含义,或者这些数值之间按照特定的关系进行”组织”,这个“表达”或者”组织”的过程就叫做编码 。
如果要将这些字节再按照相反的顺序表达出来,就是”解码”的过程,经过特定的解码方法就能得到特定的内容 。比如在一张bmp图片文件中,文件中存储的数值表示各个像素点的亮度值,而在一个文本文件中,这些数值存储的就是一些字符 。怎么区分一个文件到底是图片文件还是文本文件,一般是根据文件的后缀名称来区分的 。在操作系统里,双击一个”.bmp”文件,系统就会根据后缀”.bmp”去查找默认的图片程序打开这个文件,双击一个”.txt”文件,就会根据后缀”.txt”找到对应的文本程序打开这个文件 。此处如果抬杠的话,你要用文本程序打开图片文件也是可以的,只是并不能得到你想要的东西 。
到了这里我们清楚了不同的后缀可以对应特定的应用程序来打开,但是有些文件即使是相同的后缀,可能他内部的格式还是有差异的,这又是怎么区分的呢?比如一张bmp文件,到底表示的是黑白图片还是彩色图片、彩色图像是用16色(4位)还是24位表示的,仅仅通过后缀已经不能区分了 。
不同格式的lena图
上面的3个lena图片都是bmp的后缀,从预览效果看它的内容是有差异的,这是图片文件内部编码方式存在差异导致的 。2色图片中每个像素只需要1个bit表示,16色图中每个像素需要4个bit表示,而24位图中每个像素需要24bit表示,如果应用程序仅仅根据后缀来解码,就不能适应这种情况了 。所以在文件内部的某个位置约定其具体的编码方式,这样应用程序就能根据这个约定决定使用何种解码方式 。
桔子菌还想滔滔不绝地说下去,被橙子妹打断了:前面说的不是文本文件么,怎么又扯到图片文件上来了,扯远了,赶紧回正题 。桔子菌:不急不急,铺垫下而已,介绍些背景,接下来继续 。
好了,回到开始说的文本文件,文本文件中存储的是字符,大多是人眼可识别的字符,比如英语字母、汉字、阿拉伯数字、罗马数字等等 。计算机刚开始出现在英语世界的时候,最常用的是ASCII字符集,比如用数值65表示大写字母“A”,用数值48表示字符形式的数字“0”,ASCII字符集用数值0~127表示英文字母大小写、阿拉伯数字以及其他常用的符号 。在英语世界里ASCII字符集能做到游刃有余,但是当计算机在全世界流行起来的时候,只用7个bit的128种数值就显得杯水车薪了,况且这128种数值已经被占用了 。
这时候就出现了各种各样的字符集,比如汉字编码基本字符集,用2个字节表示一个字符,理论上就能表达65536(+1)种字符 。当然咯,实际上只定义了94个区,每个区包含94个位,最多能表示94×94=8836个字符 。用第1个字节表示区,第2个字节表示位,区的编号从1~94,位的编号也是从1~94,这是的字符集,但是表示字符时的编码需要在区和位的基础上分别加上0xA0,所以区和位的范围是0xA1~0xFE(0xA0+1~0xA0+94),这样2个字节中都没有使用小于0x7F的数值,也就能兼容ASCII编码 。另外不知道是巧合还是故意为之,0xFF也不在其编码范围内,这一点貌似设计的比较巧妙,巧妙之处后面再说 。虽然能表示8836个字符,但是实际存在一些空位,最终只收录了6763个汉字和682个非汉字图形字符,但是对付常用的汉字已经绰绰有余 。