ANSI C读书笔记系列之字符集篇----第三章 字符集和编码(II Unicode编码)

前面说过,每个国家都有一套自己的编码系统,每个国家的电脑就得装上支持自己那套编码的字符翻译系统.但你要显示其他国家的语言那估计就是乱码了,尤其在现今网络时代.大凡这时,历史总会有新的标准来解决这个问题.而且同时做这工作的有两群人.

通用多八位编码字符集(Universal Multiple-Octet Coded Character Set)简称UCS,是ISO组织从1984年起就开始研究制定一个全新的标准,标准编号为:ISO 10646,这一标准为世界各种主要语言的字符及附加符号,编制统一的内码.

统一码(Unicode)是Universal Code的缩写,是由另一个叫"Unicode学术学会"(The Unicode Consortium)的机构制定的字符编码系统.当然,他们工作的目的和上面那群人是一致的.

在1991年,Unicode学术学会与ISO国际标准化组织决定共同制订一套适用于多种语言文本的通用编码标准.Unicode与ISO 10646国际编码标准于1992年1月正式合作发展一套通用编码标准.自此,两个组织便一直紧密合作,同步发展Unicode及ISO 10646国际编码标准.

下面的分析可以让你了解到UCS与UNICODE的联系和区别了.

UCS的结构是一个四维的编码空间,每一维由一个字节(八位二进制位)组成,范围是00到FF.于是,UCS总体上分为128个群组(Group 00-7F),每一群组由256个平面(Plane 00-FF)组成,每一平面有256行(Row 00-FF),每一行256个编码位(Cell 00-FF).所以,每一平面包括65,536个字符位(Character Position 0000-FFFF).整个编码字符集的每个字符都由4个字节,按“组-面-行-列”的顺序表示.所以UCS的可编码空间为:128 × 256 × 256 × 256.UCS将其第一个平面(00群组中的00平面)称作基本多语种平面(Basic Multilingual Plane,BMP).

在UCS中,目前只有00组是重要的,Unicode学术学会断言,在可以预见的将来,甚至不可能用完00组中的前17个平面(00平面到10平面).因此,Unicode只定义了ISO 10646的第00组的前17个平面.事实上,目前绝大多数字符,都分配在第00平面BMP中.

UCS有两种方式来表示一个字符编码:四字节正规形式(UCS-4,Four-octet canonical form)和双字节基本平面形式(UCS-2,Two-octet BMP form).UCS-4用4个字节来表示一个字符.第一个字节表示组,第二表示平面,第三表示行,第四表示单元号或列.

当系统只使用BMP的字符码时,可以省略群组和平面中的八位,将字符码由32个位缩短为16个位,标记为UCS-2.

Unicode和UCS-2同样采用16位编码.所以一般可以把Unicode和UCS-2看作是同一样东西.

看到这,我们肯定有问题:2字节很容易用完吧?而且开始Unicode不是说17个平面才能保证可预见的未来足够用么?确实如此,代理对(Surrogate Pair)的设计在这种背景下应运而生.

UCS-2在BMP中开辟了一个特殊的区间(D800 - DFFF)-- 代理区,并平分成两个区,分别称为高半代理区(High-half Zone,D800 - DBFF)和低半代理区(Low-half Zone,DC00 - DFFF),各有1024个码位.使用时,从高低两个代理区中各取一个编码组成一个四字节的代理,来表示一个在BMP以外平面上的编码字符位.这样一来,总共可以多表示1024×1024个字符,映射到00群组中的01到10平面(共16个平面).

UCS只是一个字形和内码上的标准,并没有定义实际在计算机上存取的方法,即Unicode 的实现方式.应该说,对Unicode编码的实现方式根据不同平台可以有不同实现.Unicode的实现方式称为Unicode转换格式(Unicode Translation Format,简称为 UTF).

UTF-16:用定长16位(2字节)来表示的UCS-2或Unicode转换格式.它将Unicode的编码值变成2字节表示.UTF-16利用代理对来访问BMP之外的字符编码.

UTF-8: 8bit变长编码.对UCS-2,由1字节至3字节构成.如果UCS-2使用了代理对,则UTF-8最长可到4字节,对UCS-4,由1字节至6字节构成.

UTF-8的编码规则有二条:

1)对于单字节的符号,字节的第一位设为0,后面7位为这个符号的unicode码.因此对于英语字母,UTF-8编码和ASCII码是相同的.

2)对于n字节的符号(n>1),第一个字节的前n位都设为1,第n+1位设为0,后面字节的前两位一律设为10.剩下的没有提及的二进制位,全部为这个符号的unicode码.可参考下表:

   Unicode符号范围               |      UTF-8编码方式
        (十六进制)                    |        (二进制)
--------------------+---------------------------------------------
0000 0000----0000 007F   |    0xxxxxxx
0000 0080----0000 07FF   |    110xxxxx 10xxxxxx
0000 0800----0000 FFFF   |    1110xxxx 10xxxxxx 10xxxxxx
0001 0000----0010 FFFF   |    11110xxx 10xxxxxx 10xxxxxx 10xxxxxx

 

下面,还是以汉字"严"为例,演示如何实现UTF-8编码.

已知"严"的unicode是4E25(100111000100101),根据上表,可以发现4E25处在第三行的范围内(0000 0800-0000 FFFF),因此"严"的UTF-8编码需要三个字节,即格式是“1110xxxx 10xxxxxx 10xxxxxx”.然后,从"严"的最后一个二进制位开始,依次从后向前填入格式中的x,多出的位补0.这样就得到了"严"的UTF-8编码是"11100100 10111000 10100101",转换成十六进制就是E4B8A5.

介绍到这,Unicode编码历史基本上都介绍到了,这里面同样还有一个字节序问题.后面继续介绍.

 




 

 

 

 

 

 

 

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值