ANSI编码和Unicode编码的不一样-chaijunkun-CSDN

ANSI编码最多见的应用就是在Windows当中的记事本程序中,当新建一个记事本,默认的保存编码格式就是ANSI,ANSI应该算是一种压缩编码了,当遇到标准的ASCII字符时,采用单字节表示,当遇到非标准的ASCII字符(如中文)时,采用双字节表示。
Unicode编码标准已在近年来的多种新科技当中被加以采用,包含了可扩展置标语言(XML)、Java程序语言、以及最新的操做系统中。网络

下面用实验的方法来进行研究这二者之间的差异:架构

首先要准备的软件有UltraEdit,用于对文本进行比较;其次用于分析网络字节序的辅助网站http://bm.kdd.cc/index.asp
编辑器

步入正题,在一个空白的文件夹下建立一个记事本文档“新建 文本文档.txt”,在里面输入“宋体ABC(回车)”(不包含引号,最后要在ABC后输入一个回车),保存并关闭该文档,将此文件选中以后直接复制、粘 贴,在相同的文件夹下就产生了“复件 新建 文本文档.txt”,再次打开“新建 文本文档.txt”,选择菜单中的“文件”->“另存为”,在另存为对话框中,最下面有“编码”,选择Unicode。保存,选择替换。网站

然 后打开UltraEdit,在菜单中选择“文件”->“比较文件”(或直接按快捷键Alt+F11),选择第一个要比较的文件为“新建 文本文档.txt”,选择第二个要比较的文件为“复件 新建 文本文档.txt”,“比较模式”选择文件,“二方比较”,“要比较的第一个文件”为“二制”,“编辑器平铺”选择“垂直平铺”,点击“比较”,程序自动 对这两个文本文件进行比较,并以16进制的形式显示,以下图所示:
ANSI编码:编码

UNICODE编码:spa

根据分析,其表明的意义以下图所示操作系统

在用Unicode对文字进行编码时,头两个字节必定是FF FE,这样用来标识此文档以Unicode编码。下面来关注一下内容的编码部分:code

中文,做为一种ASCII字符,不可能只用一个字节来表示一个汉字,至少须要用两个字节来表示,因此,中文是一种双字节字符,下图所示的是在http://bm.kdd.cc/index.asp上查询到的“宋体”两个汉字,分别用Unicode编码和ANSI编码的十六进制内容:
ANSI编码:
文档

UNICODE编码:get

在Unicode编码中,“宋”这个汉字的编码为5B 8B,按照二进制的说法,5B是高八位,8B是低八位。然而,对照着前面所标注的结果,用Unicode编码的文本文件中, 先存储的是8B这个低八位,而后再存储的5B这个高八位,这就是Windows内部在处理Unicode字符的时候与其余系统(如Mac OS)的不一样,Windows先处理Unicode字符的低八位,而后再处理高八位;而有的系统是先处理高八位,再处理低八位,这就是为何在 Internet上要规定“网络字节序”。(2011.3.29 更正:本地字节序处 理顺序只与CPU架构有关,与操做系统无关,以前误觉得Mac OS与Windows不一样是由于Mac机以前使用的是PPC处理器,该处理器采用大端对齐方式,而从Mac OS 10.4开始出现了支持Intel x86 CPU的系统,这时基于Intel x86架构处理器的Mac机字节序变为小端对齐。另外,本文中所述Unicode编码也不严谨,应特指为UTF16编码。特此更正。)

在ANSI编码中,彻底不存在这个问题,“宋”的ANSI编码为CB CE,在存储这些字符的时候也是按照高八位,低八位的方式存储的。

以上讨论了中文在Unicode和ANSI编码中的特色,下面看一下ASCII字符在这两种编码中的特色:

在Unicode编码中,全部的字符都是以两个字节来存储的(2011.6.22 更正:在UTF-16编码格式中,并不是全部的字符都是以两个字节来存储的。若是仅仅用两个字节来存储一个字符,编码空间为2^16=65536个,这个数量连中文汉字都包含不全,因此以前的理解有误差。正确的理解是UTF-16编码是以两个字节为基本编码单位来存储的。若是一个字符超出了这两个字节所能表示的空间,则会再次申请两个字节来编码。特此更正。),而ASCII字符仅用一个字节就能够表示,那么另一个字节的内容就会被置为00。采用Unicode会产生的缺点就是:若是一篇文章里全是英文,那么,采用Unicode方式编码存储,所占用的存储空间会大约增长一倍(由于头部还要多两个字节的FF FE标识),可是采用Unicode编码的好处就是适合同一文档中采用不一样语言的文字,所以Unicode编码普遍应用于XML语言(可扩展标记语言)和编写多语言程序。

在本文的第二组图中,能够看到,采用Unicode编码的大写英文字母A,其编码为00 41(以前曾经解释了Windows在处理Unicode字符的时候先处理低八位,后处理高八位),由于Unicode存储的任何字符都占用2个字节的空间,因此在解码的时候就两个字节两个字节地取。若是发现高八位不是00,则认为这两个字节表示一个非ASCII字符,反之若是发现高八位为00,则可知,该字符为ASCII字符,因而取出低八位,再根据ASCII码表查到对应字符,由于取出的低八位认为表示的是一个ASCII字符,因此字符空间为2的8次方,也就是256个,所以采用Unicode编码表式的ASCII字符属于扩展的ASCII字符集

在第二组图的ANSI编码解释中能够看到,存储一个大写英文字母A仅用了一个字节,内容为41。十六进制的41转换为八位的二进制后应该是 01000001,能够看到,此二进制数的最高位为0,ANSI编码在存储ASCII字符时采用的是传统的ASCII字符集,其字符数量为128,正好2的7次方就是128,所以最高位必定是0。汉字“宋”的ANSI编码为CB CE,将这两个字节的十六进制数转换为二进制,结果为[11001011][11001110] ,每一个字节的最高位都是1,由此能够推断在解码的时候,一次读取一个字节的内容,看一下该字节最高位是否为1,若是为1,暂存该字节,并读取下一个字节,新读取的这个字节的最高位应该也为1,这样将两个字节合并而后去查询对应的字符;若是第一次读到的一个字节最高位为0,那么就按此字节的内容直接查询传统的ASCII码表,找到对应的字符。

最 后再分析Windows中的回车换行特色。在开始的时候为了准备这个实验用的文本文档,在输入完ABC后又输入了一个回车。可是经过分析得知,在文本存储 的时候并非仅存了一个“回车”,还存了一个“换行”,并且是先存储的“回车”后存储的“换行”(见ASCII码表:0D->回车;0A-> 换行),这与Linux/Unix中的换行方式不一样,在Linux/Unix中仅用一个0D(回车)就能够令文本换行。若是将一个在Linux/Unix 中编写的文本文档直接拷贝到Windows中打开(最简单的能够在Windows下查看百度首页的源代码),就会看到这些文字几乎都是连着的,没有换行, 那是由于在该文档中并没有显式地存储0A(换行符),虽然这篇文章在Linux/Unix中看起来很正常。

相关文章
相关标签/搜索