Unicode相关知识总结

Unicode相关知识总结

 

一、        Unicode发展历史

字符必须经过编码以后才能被计算机处理,计算机使用的默认编码方式称为计算机的内码。早期的计算机使用7位的ASCII编码作为内码,但ASCII编码只能处理2^7=128个字符(包括英文字母、数字、符号、控制字符等),但是世界上有着成百上千种的语言,仅仅用ASCII是无法进行处理的。因此,世界各国开始纷纷研究处理本国语言的方法。在中国为了处理汉字,程序员设计了用于简体中文的GB2312编码和用于繁体中文的big5编码。

 

中国各种编码标准的情况:

1980年公布的GB2312编码标准一共收录了7445个字符,包括6763个汉字和682个其它符号。

GB2312 支持的汉字太少。1995年公布的汉字扩展规范GBK1.0则收录了21886个符号,它分为汉字区和图形符号区,汉字区包括21003个字符。

     2000年发布的GB18030正式取代GBK1.0成为国家标准,该标准收录了27484个汉字,同时还收录了藏文、蒙文、维吾尔文等主要的少数民族文字,所以现在的PC平台必须支持GB18030标准。

 

 

光是在中国就有那么多种不同的编码方式,世界各国编码方式的混乱情况就可想而知了。于是人们开始寻求一种统一的标准编码方法来表示和处理世界上绝大多的语言,众多的编码方法中最后只有Unicode编码最终成为了事实标准。

Unicode字符集编码是(Universal Multiple-Octet Coded Character Set 通用多八位编码字符集的简称,支持世界上超过650种语言的国际字符集。它是由一个名为 Unicode 协会(Unicode Consortium)的机构制订的字符编码系统,支持现今世界各种不同语言的书面文本的交换、处理及显示。该编码于1990年开始研发,1994年正式公布,最新版本是2005331日的Unicode 4.1.0Unicode协会的官方网站是http://www.unicode.org,上面有关于Unicode的最新消息与最权威的资料。

 

二、        Unicode编码术语解释

UCSUniversal Multiple-Octet Coded Character Set(通用多八位编码字符集)的字符集,也可以以看作是"Unicode Character Set"的缩写。有UCS-2和UCS-4两种不同的实现方法,UCS-2采用两个字节进行编码,而UCS-4采用4个字节(实际上只用了31位,最高位必须为0)进行编码。

UTF编码:UCS Transformation Format(UCS转换格式),它是将Unicode编码规则和计算机的实际编码对应起来的一个规则,用于网络传输、编码转换等。

Little Endian/Big Endian:字节序,也就是处理多字节时采用的顺序,例如:“南”字的Unicode编码是5357,字节序将决定它写到文件里时,是53在前还是57在前,如果是Big Endian则写为5357,反之则是5753

 

三、        Unicode编码中的数学

1、  UCS-2使用2个字节,即16位来编码,所以共可以表示216=65536个码元;UCS-4使用4个字节,即32位来编码,但最高位必须为0,所以共可以表示231=2147483648个码元。

2、UCS-4码元的管理:由于UCS-4表示的码元非常大,所以需要采用一种机制来管理这些码元。UCS-4先根据最高字节不同分为27=128个群组,再根据第二个字节不同分为28=256个平面,然后根据第三个字节不同分为28=256行,最后根据第四个字节不同分为每行分为256个单元。也就是说同一行的不同单元只是最后一个字节不同,其余都相同。

3、UCS-4编码中,群号为0,平面号为0的所有码元称之为BMP,即Basic Multilingual Plane(基础多语言平面)。

4、将UCS-4的BMP去掉前面的两个零字节就得到了UCS-2。在UCS-2的两个字节前加上两个零字节,就得到了UCS-4的BMP。

这些数据和关系可以由下图清楚的得到:

 

 

群号: 0~127

 

 

平面号: 0~255

 

 

行号: 0~255

 

 

单元号: 0~255

 


0

x

x

x

x

x

x

x

x

x

x

x

x

x

x

x

x

x

x

x

x

x

x

x

x

x

x

x

x

x

x

x

 

UCS4-编码示意图

 

0

0

0

0

0

0

0

0

0

0

0

0

0

0

0

0

x

x

x

x

x

x

x

x

x

x

x

x

x

x

x

x

UCS-4 BMP编码示意图

 

x

x

x

x

x

x

x

x

x

x

x

x

x

x

x

x

UCS-2编码示意图

 

 

四、        Unicode编码的问题及解决方法

Unicode里,所有的字符被一视同仁。像拆字、统计字数这些问题也就很容易解决。但是,也不可能在一夜之间所有的系统都使用Unicode来处理字符,所以Unicode从一开始,就必须考虑一个问题:和ASCII字符集之间的不兼容问题。比如字符“A”的ASCII码是65,而它的Unicode码则是0065,这就造成了一个非常大的问题:以前处理ASCII的那套机制不能被用来处理Unicode了。另一个更加严重的问题就是,C语言使用'/0'作为字符串结尾,而Unicode里恰恰有很多字符都有一个字节为0,这样一来,C语言的字符串函数将无法正常处理Unicode,除非把世界上所有用C写的程序以及他们所用的函数库全部换掉,这明显不可能做到。

事实证明,对可以用ASCII表示的字符使用UNICODE并不高效,因为UNICODE比ASCII占用大一倍的空间,而对ASCII来说高字节的0对他毫无用处。为了解决这个问题,就出现了一些介于ASCII和UNICODE中间格式的字符集,但他们本质也是UNICODE编码。他们被称为通用转换格式,即UTF(Universal Transformation Format)。它不像Unicode码一样只停留在理论基础上,它是真实地存在于计算机中的。

 

五、        UTF相关知识

目前存在的UFT系列编码标准有:UTF-7、UTF-7.5、UTF-8、UTF-16、UTF32五种,UTF-8和UTF16比较常用,下面分别介绍:

UTF-8:它是UNICODE的一种变长字符编码标准,现在已经标准化为RFC 3629。使用1到6个字节来编码UNICODE字符。UTF-8里英文字符仍然跟ASCII编码一样,因此原先的函数库可以继续使用。下面的表是它与Unicode编码之间的对应关系,接下来的算法也会用到。

 

Unicode

UTF-8

00000000 - 0000007F

0xxxxxxx 

00000080 - 000007FF

110xxxxx 10xxxxxx 

00000800 - 0000FFFF

1110xxxx 10xxxxxx 10xxxxxx 

00010000 - 001FFFFF

11110xxx 10xxxxxx 10xxxxxx 10xxxxxx 

00200000 - 03FFFFFF

111110xx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx 

04000000 - 7FFFFFFF

1111110x 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx 

后面三个范围段里的Unicode编码,目前尚未使用到,所以一般不予考虑。这个表也称为字节模板,用于UTF-8与Unicode之间的转换.转换方法就是先确定编码所需要的字节数,然后用UNICODE编码二进制位从低位到高位依次填入上面表示为x的位上,不足的高位以0补充。举例说明:汉字“码”的Unicode编码十六进制为0x7801,落在第三个范围内,所以要用3个字节来表示,把0x7801转换为二进制111100000000001;按照字节模板写成:111  100000  000001的形式,然后用字节模板填充为:11100111 10100000 10000001,再转化为十六进制就得到了“码”的UTF-8编码为E7A081。这样以字节为编码单元,没有字节序的问题。

UTF-16:以16位为单元对Unicode进行编码。对于小于0x10000的UCS码,UTF-16编码就等于UCS码对应的16位无符号整数。对于≥ 0x10000的UCS码,定义了一个算法。不过由于实际使用的UCS2,或者UCS4的必然小于0x10000,所以就目前而言,可以认为UTF -16和UCS-2基本相同,如果不加特别说明,UTF-16基本上可以等同于Unicode和UCS-2。但UCS-2只是一个编码方案,UTF-16却要用于实际的传输,所以就不得不考虑字节序的问题,Unicode规范中推荐的标记字节顺序的方法是BOM(Byte Order Mark):字节序标识符。

Unicode编码中有一个叫做"ZERO WIDTH NO-BREAK SPACE"的字符,它的编码是FEFF。而FFFE在UCS中是不存在的字符,所以不应该出现在实际传输中。UCS规范建议我们在传输字节流前,先传输字符"ZERO WIDTH NO-BREAK SPACE",而这个字符按照上述算法转换到UTF-8得到的是EF BB BF。这样如果接收者收到FEFF,就表明这个字节流是BigEndian的;如果收到FFFE,就表明这个字节流是LittleEndian的。因此字符"ZERO WIDTH NO-BREAK SPACE"又被称作BOM,而如果接收到以EF BB BF开头的字节流,则说明这个字节流是用UTF-8来编码的。

 

2006-03-06补充关于代理对(Surrogate Pair)的相关内容:

为了发展,Unicode在BMP定义了一个代理区(Surrogate Zone)(D800至DFFF), 并将这个区域平分为前后两个各容纳1024(1K)个编码的区域(D800-DBFF及DC00-DFFF),分别称作高半代理(High Surrogate)及低半代理(Low Surrogate)区域。从这两个区域分别各取一个编码,分别称为高半代理键(High Surrogate Key)及低半代理键(Low Surrogate Key),由这两个Key组合成一个4字节代理对(Surrogate Pair)来表示一个编码字符。由于这两个区域内并没有定义任何的字符或符号,而且只有将这两个代理对(Surrogate Pair)结合在一起才能表示一个字符,单独使用其中的任何一个都没有意义。所以一个现有的应用程序无论何时遇到输入来自此两块保留区的任何一个编码时,它都是没意义的。

Surrogate机制可对应到一百万个字符(1024x1024=1,048,576),这一百万个字符分别对应到ISO 10646 中00组的00至0F这16个字面(plane),每一个字面的容量为64K(256x256),CJK扩展集B,位于第二个字面(plane 2),第14, 15个字面(plane 15, 16)则留做用户自定义区域(user private area)。  

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值