tqsheng

go.....
随笔 - 366, 文章 - 18, 评论 - 101, 引用 - 0
数据加载中……

记事本

c在保存一篇新建的文档时,如果没有指定编码类型,会使用缺省的ANSI类型(对于中文版来说,对应的就是GB码)。
而在打开一篇已创建的文档时,它会分析文档的编码类型,它首先判断文档头部有无BOM(Byte Order Mark,字节序标记,长
度为(2-3字节),如有则根据其内容判断编码类型,FF、FE(Unicode),FE、FF(Unicode big endian),EF、BB、BF(UTF-8) 
因为事实上有很多非ANSI编码的文档是没有任何BOM的“纯文本”,所以对这些文档不能简单的判断为ANSI编码。
而需要使用一系列的统计学算法根据文档内容来猜测文档编码。记事本使用了 IsTextUnicode 函数来判断是否为 
Unicode/Unicode big endian 编码,使用 IsTextUTF8 判断是否为 UTF8 编码。但既然是统计学算法,就难免存在误判
,尤其在文档内容过短时,由于样本的容量太小,这种误判的概率会显著增大。比如那个有名的微软与联通有仇的笑话,
就是记事本在打开只有"联通"二字的ANSI编码文档时,IsTextUTF8 函数将其误判为UTF8编码[2];同样的误判也发生在 
IsTextUnicode 函数上,比如具有 “this app can break”这种具有4335结构的文档,会被误判为 Unicode 编码[3][4]。
需要说明的是,这种误判的可能性是建立在文本较短且其字节位特征不被干扰的前提上的。如果将上述的文本做稍许修改(即使只是增加一个回车),则误判很难再发生。
而这种方法的特殊性在于,它的字节串不但具有Unicode特征,而且很长达到了1288字节,也就是说它的Unicode特征性很强,所以可以抵抗一 些较短的不具有Unicode特征串的干扰,这是由统计学的规律所决定的。但是在干扰串稍长时,Unicode的特征将会受到显著干扰,直至被 IsTextUnicode 函数认定为非 Unicode。所以,有些朋友总是无法测试成功,应该是与附加的批处理代码长度和内容相关。
因为其他的编辑器(比如 Word / Wordpad / EditPlus / UltraEdit)使用了更新的编码类型判断算法,所以在 Unicode 判断上改进了不少,而 UTF8 的判断仍然不尽如人意。但因为理论上来说完全准确地算法并不存在,所以我们只能依靠避免使用无BOM的非ANSI文档,或者打开文档时手动指定编码类型。
   另外,如果使用记事本保存了这些误判了编码类型的文件,则将难以恢复。如果使用误判编码保存,则将给原文档加上BOM标记,则使用其他编辑器也再无法 观察到原文档。如果使用 ANSI 编码保存,则原文档将会被当作 Unicode 文档而被转换,还原的可能性接近于零

posted on 2012-07-13 20:59 tqsheng 阅读(146) 评论(0)  编辑 收藏 引用


只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理