有趣的Unicode的BOM

《有趣的Unicode的BOM》,这个文章标题抄自周曙光的网络日志这篇同名文章。抄标题的原因,详见文章末尾。呃,看到这里,你的手动了没?动了就是好奇心很强的人。如果是用鼠标拖动滚动条,电脑白痴;按PageDown键或者End键,电脑菜鸟;按Space键或者滚动鼠标滚轮,电脑高手。因为,“不知道IE工具栏第一个按钮的功能的,是普通用户;知道的,是高端用户。”

今天偶然看到那篇文章。(没有订feed看的习惯,555~~)Unicode这玩意很简单,又很复杂,值得好好研究。BOM这东西,有人说它是好东西,有人说它是罪魁祸首,反正说什么的都有。

文章提到3个问题,前两个是我所熟知的,最后一个我是第一次听说,而且在Google搜索一下,只有两个网站提到,自然,一个是我看的这篇文章,一个就是该问题的出处咯。

用Windows记事本写txt文件,在文件开头加入".LOG"字样,那么在每次打开文件时,记事本会自动在文件最后加上当前日期。这个是N久以前的,在Windows 98的时代就有的一个特性。我还记得当时Windows 98发布时,报纸上经常提到这个技巧,说是Windows 98的新功能。另外,微软网站的文档《How to Use Notepad to Create a Log File》里也介绍了这一技巧。(当年Windows 98发布时,我是多么的激动啊,现在的Vista已经没感觉了,唉,年轻不再)这个小技巧好像直到现在还是经常被提起,比如在各大电脑杂志上。而且,经常有人说这是复活节彩蛋。拜托,按下Ctrl+R,输入winrar,回车,点帮助,关于,点一下上面的图片和左边的图标,那个叫复活节彩蛋。隐藏在你身边,在某个值得纪念的日子,比如复活节,被开发商公布看到的办法,或者是你偶然发现,得到的一个惊喜,那个才叫复活节彩蛋。

联通的问题。“联通”二字的编码是"C1AACDA8",当记事本读取的时候会出现判断错误,认为这是一个UTF-8编码文件,以UTF-8编码方式打开,所以出现错误。虽然显示出来的是一个黑块,不过可并不是只有一个字符哦。C1AA的二进制是1100000110101010,按照UTF-8两字节来拆开,Unicode编码是1101010,也就是6A,而两字节的UTF-8要在80以上才能使用,所以这个UTF-8编码是不存在的,所以记事本不显示。而CDA8,二进制1100110110101000,拆开的Unicode编码是1101101000,也就是368。在宋体字符里查了一下,查不到,不知道是那个国家的编码,反正是显示不出来就是了,只能显示一个黑块。所以,文章最后给出的答案,“第一种情况是将联通的Unicode编码54801A90当成ASCII编码解析,所以出现一些方块乱码”,乱讲。还有xfocus论坛2004年1月的这个帖子,说4个字节中,前3个字节被当作BOM,只有第四个字节显示出来,乱讲 too. 不过,能知道UTF-8的BOM是3个字节,已经很高手了。

第三个问题,在记事本中输入"this sentences are notreadable",保存后再打开时变成中文乱码。这个事也是编码判断错误。其实想看记事本把它错误判断成什么编码是很简单的,在打开文件后,点文件->另存为,下面的编码一项就是记事本所认为的文本的编码方式。另外,在文件->打开里,选中一个文本文件,记事本也会立即进行识别,并把认为的编码方式显示在对话框下面的编码项中。(起码在我的Windows XP SP2里是这样的)这个字符写入文件后会被记事本认为是所谓的"Unicode"编码,也就是UTF-16编码。这也是记事本对编码判断的错误。xfocus论坛的那个帖子,说是什么Unicode头,乱讲 too.

联通的问题和第三个问题,都是记事本编码判断错误的问题。这显然不是复活节菜单,也算不上bug。你不告诉软件所打开的文件的编码方式,他当然只能猜咯。猜总是会猜错的嘛。比如行尾符的问题,假如你的文件里就没有换行符,软件又怎么能给你判断呢?不止记事本,就是UEStudio,在打开有“联通”那两个字的文件时,也是认为是UTF-8编码,而且它还把C1AA这个编码给解析出来了,6A对应的字符的小写字母"j",它给显示出来了。不过,经常在网上或者电脑杂志看到这个火星贴被翻出来,还大都加上什么“已经打了最新的SP2”补丁之类的。唉,就知道SP2,SP2出来很久了,那么多Hotfix打了没啊?

最后,该点题了。“有趣的Unicode的BOM”,其实是最可怜的BOM。上述三个问题,和BOM一点关系都没有,可是后两个所谓的“Windows的bug”却被硬赖在BOM身上。我们的BOM,我们的Byte Order Mark,是多么的可怜啊。其实记事本在UTF-8和UTF-16编码的文件开头写入BOM并没有错,因为下次再用记事本打开的时候它就好识别了呀。那么多电脑菜鸟,有谁会在发现乱码之后,在打开对话框里调一下,选择一个正确的编码啊?只会脱口而出:“Windows的bug,Windows真难用。”

P.S. 后两个问题可以作为测试题。当别人回答你“不知道”的时候,电脑白痴;回来“是编码的问题”,电脑菜鸟;提到"Unicode",电脑高手;要是提到BOM,这个人你一定要抓住啊,他就是所谓的牛人啊。在这个知道IE工具栏第一个按钮的功能就是高手的年代,能吐出"BOM"三个字,那是多么牛的人啊,虽然,虽然BOM和这两个问题一点关系都没有。

PS2 找到新浪的一篇报道《微软记事本“闹鬼” 常用汉字输入变黑点》,2003年的,或许联通的问题就是2003年才出现的吧。还有这篇《关于“微软/联通”记事本问题的解释》,介绍的也很详细。“当文档中所有字符都在C0≤AA≤DF,80≤BB≤BF这个范围的时候,notepad都无法确认文档的格式,没有自动按照UTF-8格式来"Display"。”这话好像说反了,如果所有字符都在(C0-DF, 80-BF)这个范围内,文件就会被以UTF-8编码解析。至于原因嘛,嘿嘿,这个范围正好是UTF-8两字节编码的范围:110xxxxx 10xxxxxx (c0-df)(80-bf)。而我觉得,事实上Windows记事本所采用的判断编码的策略,其实就是以UTF-8编码方式解码,如果解码过程没有出现错误,也就是说这个文件按UTF-8编码方式解码没有问题,没有不符合UTF-8编码的字节,那么,记事本就认为他就是一个UTF-8文件。这也是没办法,对于没有BOM的文件来说,只有这个办法。而且,在PHP里判断编码方式也是用的这种办法,我写的程序也是用的这种办法,想要更好的办法?更好的办法就涉及到解析字符串,分析出里面句子的意思,判断是否是符合逻辑的句子了。

本文共有 11 条评论有趣的Unicode的BOM


  1. 1 fishee

    I use right click, mouse action, haha.

  2. 2 yskin

    Maxthon还是GreenBrower还是Firefox还是Opera?

  3. 3 Moses

    记事本对 UTF-8 文件强加 BOM 并不是很好的做法.

    试想如果你写 UTF-8 编码的 HTML, 按照 W3C 要求, 是不需要加 BOM 的, 记事本的做法将会导致无法通过 W3C 验证, 并且使用普通办法还很难将记事本加入的 BOM 去掉.

    对于 UTF-16, 强制加 BOM 是正确的做法, 但对于 UTF-8, 应该让用户自己选择加不加 BOM. 因为 BOM 对 UTF-8 一般是无用的.

    Windows 记事本的处理欠妥.

  4. 4 yskin

    强加是不好地,要是微软在记事本里提供个"UTF-8 without BOM"就好了。

    在html,PHP程序里,BOM是会造成很大影响的,尤其是PHP程序很多的时候,在包含文件的时候由于有BOM的存在导致程序有输出,从而使后面的header命令失效。

    不过,既然做程序设计,总不至于用记事本吧,总会用一些别的编辑器。最近两三个月,我用的UEStudio貌似已经不会再强行写入BOM了,现在好用多了。对于不懂IE工具栏第一个按钮意思的普通用户来说,微软或许有她的考虑。比如,在记事本中如果有不包含在当前代码页的字符时,保存时会出现“该文件含有 Unicode 格式的字符,当文件保存为ANSI编码的文本文件时,该字符将丢失。要保存 Unicode 信息,单击下面的‘取消’,然后从编码列表中选择一个 Unicode 选项。继续吗?”单纯考虑记事本编辑文本文件,只用于记事本打开阅读的情况,写入BOM确实是个标识文件的好办法。

  5. 5 DonauYa

    IE工具栏第一个按钮?我不用IE怎么办?

  6. 6 conpeo

    所以yskin你特地设置插件为UNIX UTF-8格式,既可以防止有人用记事本修改文件?

  7. 7 yskin

    包含中文的插件,自然要用UTF-8编码。而用UNIX格式,因为记事本无法识别UNIX行尾符,所以。。。

  8. 8 中国年

    记事本没有对 UTF-8 文件强加 BOM , 如果选择Unicode保存,则没有BOM

  9. 9 中国年

    sorry 说错了

  10. 10 charset

    写得很好。欢迎访问字符集编码研究[::blog::]
    http://www.charset.cn/blog/

  1. 1 有趣的Unicode的BOM - Beoo.de
    Pingback2007-1-8 8:49 下午

请留下您的评论: