- 积分
- 70
- 实力分
- 点
- 金钱数
- 两
- 技术分
- 分
- 贡献分
- 分
|
发表于 2007-6-5 16:05:35
|
显示全部楼层
回复 #8 春晖 的帖子
这个情况是Ansi(这里其实应该是GBK或者GB2312之类的)的被认成UTF-8而产生的
GB2312, GBK都是二字节的编码,在ASCII上扩展来的,“联通”两个字的 GB2312/GBK编码是:
联 C1AA
通 CDA8
而UTF-8是一种变长的编码,对应了Unicode,其对应关系如下:
U-00000000-U-0000007F: 0xxxxxxx
U-00000080-U-000007FF: 110xxxxx 10xxxxxx
U-00000800-U-0000FFFF: 1110xxxx 10xxxxxx 10xxxxxx
U-00010000-U-001FFFFF: 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
U-00200000-U-03FFFFFF: 111110xx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx
U-04000000-U-7FFFFFFF: 1111110x 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx
其中U开头的是Unicode编码,冒号后面是二进制表示的UTF-8编码,这样的话,UTF-8就有着一些显然的特征了。
windows 的记事本在保存的时候保存成Ansi的,如果手工的保存成UTF-8,Unicode,Unicode large endian之类的其它编码的话,记事本会在文件的开始加入一个标志,这个标志叫做BOM(Byte Order Mark,字节顺序标志),而这里面的Unicode和Unicode large endian又有什么分别呢?其实应该说成Unicode little endian和Unicode large endian,分别其实就是在把编码存储的时候把多字节的高位放在前面还是后面的区别。
这三种编码对应的BOM分别如下:
UTF-8: EFBB
Unicode: FFFE
Unicode big endian: FEFF
BOM听说是不会在文本中出现的,所以可以用来作为标志。
而记事本打文件的时候会根据BOM来判断文件使用的编码,这看来是没什么问题,最多打开没有BOM但是UTF-8/Unicode/Unicode big enddian之类的文件出现问题,但是头痛的是,记事本不仅仅根据BOM来判断,它还会根据上面UTF-8编码的特征来猜测文本是不是UTF-8编码的。
把联通两个字的GB2312/GBK编码转换成二进制:
联:
C 1 A A
1100 0001 1010 1010
通:
C D A 8
1100 1101 1010 1000
所以存在文件中的时候的情况用二进制表示就是(中间空格是为了分开两个字):
1100000110101010 1100110110101000
这样的情况很显然是符合U-00000080 - U-000007FF: 110xxxxx 10xxxxxx这种对应关系的,所以记事本再次打开的时候就会把这个文本当作UTF-8编码的,这当然就会出现问题。
其实,记事本在打开这样的文本之后,如果再保存的话,就会自动加入UTF-8的BOM,所以,在打开了刚刚那个文本之后如果删除了里面的内容之后再写入“联通”两个字之后保存,再打开就不会出现问题,记事本把这个文档存成了UTF-8格式的,因为它认为你编辑的是UTF-8的文本。
不看记事本的这个问题,单独看BOM,也是存在问题的,当试着把多个文件用程序合并的时候,会存在这样的问题:使用的程序必需能处理BOM,否则的话,文本文档的中间(非开始部分)就会出现非法的内容(BOM),而一但程序处理了BOM,那这个程序就得单独为文本模式和二进制模式编写代码,因为在二进制中FFFE, FEFF,EFBB都是合法的,所以不能去除,这无疑麻烦了,所以在找这样的软件或者是写这样的软件的时候都变得麻烦了。
而且,有些程序在处理文本的时候并不处理BOM,这样的话,在使用这样的软件的时候就会出现莫名其妙的问题,所以我个人还是比较讨厌BOM的。
另外:“endian”这个词出自《格列佛游记》。小人国的内战就源于吃鸡蛋时是究竟从大头(Big-Endian)敲开还是从小头(Little-Endian)敲开,由此曾发生过六次叛乱,一个皇帝送了命,另一个丢了王位。
这个是我之前在verycd的计算机版说的,在这去了一些无关的东西 |
|