Unicode(统一码、万国码、单一码)是一种在计算机上使用的字符编码。它为每种语言中的每个字符设定了统一并且唯一的二进制编码,以满足跨语言、跨平台进行文本转换、处理的要求。1990年开始研发,1994年正式公布。随着计算机工作能力的增强,Unicode也在面世以来的十多年里得到普及。
Unicode的编码和实现
大概来说,Unicode编码系统可分为编码方式和实现方式两个层次。
1.编码方式
Unicode的编码方式与ISO10646的通用字元集(亦称[通用字符集])(Universal Character Set,UCS)概念相对应,目前的用于实用的Unicode版本对应于UCS-2,使用16位的编码空间,也就是每个字符占用2个字节。
统一字符编码标准是一种十六位的字符编码标准,而ASCII则是七位编码,只适用于英文。另有西欧国家所用的ISO Latin-1八位编码。使用Unicode的好处就是用一个字符集就可解决所有现今世界上的可书写语言。Unicode共有2^16即65536个编码,其中有近39000种已被定义完成,而中国字就占了21000种 !
上述16位Unicode字符构成基本多文种平面(Basic Multilingual Plane,简称(BMP)。最新(但未实际广泛使用)的Unicode版本定义了16个辅助平面,两者合起来至少需要占据21位的编码空间,比3字节略少。但事实上辅助平面字符仍然占用4字节编码空间,与UCS-4保持一致。未来版本会扩充到ISO10646-1实现级别3,即涵盖UCS-4的所有字符。UCS-4是一个更大的尚未填充完全的31位字符集,加上恒为0的首位,共需占据32位,即4字节。理论上最多能表示2^31个字符,完全可以涵盖一切语言所用的符号。
BMP字符的Unicode编码表示为U+hhhh,其中每个h代表一个十六进制数位。与UCS-2编码完全相同。对应的4字节UCS-4编码后两个字节一致,前两个字节的所有位均为0。
2.实现方式
Unicode的实现方式不同于编码方式。一个字符的Unicode编码是确定的。但是在实际传输过程中,由于不同系统平台的设计不一定一致,以及出于节省空间的目的,对Unicode编码的实现方式有所不同。Unicode的实现方式称为Unicode转换格式(Unicode Translation Format,简称为UTF)。
再如,如果直接使用与 Unicode 编码一致(仅限于 BMP 字符)的 UTF-16 编码,由于每个字符占用了两个字节,在Macintosh (Mac)机和PC机上,对字节顺序的理解是不一致的。这时同一字节流可能会被解释为不同内容,如某字符为十六进制编码4E59,按两个字节拆分为4E和59,在Mac上读取时是从低字节开始,那么在Mac OS会认为此4E59编码为594E,找到的字符为“奎”,而在Windows上从高字节开始读取,则编码为 U+4E59 的字符为“乙”。就是说在Windows下以UTF-16编码保存一个字符“乙”,在Mac OS里打开会显示成“奎”。此类情况说明UTF-16的编码顺序若不加以人为定义就可能发生混淆,于是在 UTF-16 编码实现方式中使用了大尾序(Big-Endian, 简写为UTF-16 BE)、小尾序(Little-Endian, 简写为UTF-16 LE)的概念,以及可附加的BOM(Byte Order Mark)解决方案,目前在PC机上的Windows系统和Linux系统对于UTF-16编码默认使用UTF-16 LE。(具体方案参见UTF-16)
此外Unicode的实现方式还包括UTF-7、Puny code、CESU-8、SCSU、UTF-32等,这些实现方式有些仅在一定的国家和地区使用,有些则属于未来的规划方式。目前通用的实现方式是UTF-16小尾序(BOM)、UTF-16大尾序(BOM)和UTF-8。在微软公司Windows XP操作系统附带的记事本中,“另存为”对话框可以选择的四种编码方式除去非Unicode编码的ANSI外,其余三种“Unicode”、“Unicode Big Endian”和“UTF-8”即分别对应这三种实现方式。
目前辅助平面的工作主要集中在第二和第三平面的中日韩统一表意文字中,因此包括GBK、GB18030、Big5等简体中文、正体中文、日文、韩语以及越南字符的各种编码与Unicode的协调性被重点关注。考虑到Unicode最终要涵盖所有的字符,从某种意义而言,这些编码方式也可视作Unicode的出现于其之前的既成事实的实现方式,如同ASCII及其扩展Latin-1一样,后两者的字符在16位Unicode编码空间中的编码第一字节各位全为0,第二字节编码与原编码完全一致。但上述东亚语言编码与Unicode编码的对应关系要复杂得多。
非Unicode环境
在非Unicode环境下,由于不同国家和地区采用的字符集不一致,很可能出现无法正常显示所有字符的情况。微软公司使用了代码页(Code page)转换表的技术来过渡性地部分解决这一问题,即通过指定的转换表将非Unicode的字符编码转换为同一字符对应的系统内部使用的Unicode编码。可以在“语言与区域设置”中选择一个代码页作为非Unicode编码所采用的默认编码方式,如936为简体中文GBK,950为正体中文Big5(皆指PC上使用的)。在这种情况下,一些非英语的欧洲语言编写的软件和文档很可能出现乱码。而将代码页设置为相应语言中文处理又会出现问题,这一情况无法避免。从根本上说,完全采用统一编码才是解决之道,但目前上无法做到这一点。
代码页技术现在广泛为各种平台所采用。UTF-7的代码页是65000,UTF-8的代码页是65001。
XML和Unicode
XML及其子集HTML采用UTF-8作为标准字集,理论上我们可以在各种支持XML标准的浏览器上显示任何地区文字的网页,只要电脑本身安装有合适的字体即可。可以利用&#nnn;的格式显示特定的字符。nnn代表该字符的十进制Unicode代码。如果采用十六进制代码,在编码之前加上x字符即可。但部分旧版本的浏览器可能无法识别十六进制代码。
然而部分由于Unicode版本发展原因,很多浏览器只能显示UCS-2完整字符集也即现在使用的Unicode版本中的一个小子集。
输入Unicode
除了输入法外,操作系统会提供几种方法输入Unicode。像是Windows2000之后的Windows系统就提供一个可点击的表。例如在Microsoft Word之下,按下Alt键不放,输入0和某个字符的Unicode编码(十进制),再松开Alt键即可得到该字符,如Alt+033865会得到Unicode字符叶。另外按Alt+X组合键,MSWord也会将光标前面的字符同其十六进制的四位Unicode编码进行互相转换。
Unicode目前已经有5.0版本。世界上有一大批计算机、语言学等科学家专门研究Unicode,到了现在Unicode标准已经不单是一个编码标准,还是记录人类语言文字资料的一个巨大的数据库,同时从事人类文化遗产的发掘和保护工作。
对于中文而言,Unicode16编码里面已经包含了GB18030里面的所有汉字(27484个字),目前Unicode标准准备把康熙字典的所有汉字放入到Unicode32bit编码中。
UTF-8
UTF-8(8 位元 Universal Character Set/Unicode Transformation Format)是一种针对Unicode的可变长度字符编码。它可以用来表示Unicode标准中的任何字符,且其编码中的第一个字节仍与ASCII相容,这使得原来处理ASCII字符的软件无需或只需做少部份修改,即可继续使用。因此,它逐渐成为电子邮件、网页及其他储存或传送文字的应用中,优先采用的编码。
UTF-8使用一至四个字节为每个字符编码:
128个US-ASCII字符只需一个字节编码(Unicode范围由U+0000至U+007F)。
带有附加符号的拉丁文、希腊文、西里尔字母、亚美尼亚语、希伯来文、阿拉伯文、叙利亚文及它拿字母则需要二个字节编码(Unicode范围由U+0080至U+07FF)。
其他基本多文种平面(BMP)中的字符(这包含了大部分常用字)使用三个字节编码。
其他极少使用的Unicode辅助平面的字符使用四字节编码。
对上述提及的第四种字符而言,UTF-8使用四个字节来编码似乎太耗费资源了。但UTF-8对所有常用的字符都可以用三个字节表示,而且它的另一种选择,UTF-16编码,对前述的第四种字符同样需要四个字节来编码,所以要决定UTF-8或UTF-16哪种编码比较有效率,还要视所使用的字符的分布范围而定。不过,如果使用一些传统的压缩系统,比如DEFLATE,则这些不同编码系统间的差异就变得微不足道了。因为传统压缩算法在压缩较短文字时的效果不大,可以考虑使用Standard Compression Scheme For Unicode(SCSU)。
Unicode字符的位元被分割为几部分,并分配到UTF-8的字节串中较低的位元的位置。在U+0080的以下字符都使用内含其字符的单字节编码。这些编码正好对应7位元的ASCII字符。在其他情况,有可能需要多达4个字符组来表示一个字符。这些多字节的最高有效位元会设定成1,以防止与7位元的ASCII字符混淆,并保持标准的字节主导字串(standard byte-oriented string)运作顺利。
原文地址:https://www.cnblogs.com/youpeng/p/10991271.html