Unicode Version 5.1 Released
Mountain View, CA, April 4, 2008 – The
Unicode Consortium is pleased to announce the release of Unicode 5.1. This
release contains over 100,000 characters, and provides significant additions and
improvements that extend text processing for software worldwide. Some of the key
features are: increased security in data exchange, significant character
additions for Indic and South East Asian scripts, expanded identifier
specifications for Indic and Arabic scripts, improvements in the processing of
Tamil and other Indic scripts, linebreaking conformance relaxation for HTML and
other protocols, strengthened normalization stability, new case pair stability,
plus others given below.
The Version 5.1.0 data files and documentation
are final and posted on the Unicode site. In addition to updated existing files,
implementers will find new test data files (for example, for linebreaking) and
new XML data files that encapsulate all of the Unicode character properties. For
details, see the page for Unicode 5.1.0 at
http://www.unicode.org/versions/Unicode5.1.0/.
A major feature of Unicode
5.1.0 is the enabling of ideographic variation sequences. These sequences allow
standardized representation of glyphic variants needed for Japanese, Chinese,
and Korean text. The first registered collection, from Adobe Systems, is now
available at http://www.unicode.org/ivd/.
Unicode 5.1 contains
significant changes to properties and behavioral specifications. Several
important property definitions were extended, improving linebreaking for Polish
and Portuguese hyphenation. The Unicode Text Segmentation Algorithms, covering
sentences, words, and characters, were greatly enhanced to improve the
processing of Tamil and other Indic languages. The Unicode Normalization
Algorithm now defines stabilized strings and provides guidelines for buffering.
Standardized named sequences are added for Lithuanian, and provisional named
sequences for Tamil.
Unicode 5.1.0 adds 1,624 newly encoded characters.
These additions include characters required for Malayalam and Myanmar and
important individual characters such as Latin capital sharp s for German.
Version 5.1 extends support for languages in Africa, India, Indonesia, Myanmar,
and Vietnam, with the addition of the Cham, Lepcha, Ol Chiki, Rejang,
Saurashtra, Sundanese, and Vai scripts. Scholarly support includes important
editorial punctuation marks, as well as the Carian, Lycian, and Lydian scripts,
and the Phaistos disc symbols. Other new symbol sets include dominoes, Mahjong,
dictionary punctuation marks, and math additions. This latest version of the
Unicode Standard has exactly the same character assignments as ISO/IEC
10646:2003 plus Amendments 1 through 4.
The Unicode Collation Algorithm
(UCA), the core standard for sorting all text, is also being updated at the same
time (see http://www.unicode.org/reports/tr10/). The major changes in UCA
include coverage of all Unicode 5.1 characters, tightened conformance for
canonical equivalence, clearer definitions of internationalized search and
matching, specifications of parameters for customizing collation, and
definitions of collation folding. There are also important clarifications on the
use of contractions (such as "ch" in Slovak) in collation.
The next
version of the Unicode locale project (CLDR) is also being prepared on the basis
of Unicode 5.1, and is now open for public data submission (see
http://www.unicode.org/cldr/).
About The Unicode Consortium
The
Unicode Consortium is a non-profit organization founded to develop, extend and
promote use of the Unicode Standard and related globalization
standards.
The membership of the consortium represents a broad spectrum
of corporations and organizations in the computer and information processing
industry. Members are: Adobe, Apple, Basis Technology, Denic e.G., Google,
Government of India, Government of Pakistan, Government of Tamil Nadu, HP, IBM,
JustSystems, Microsoft, Oracle, SAP, Sun Microsystems, Sybase, The University of
California at Berkeley, Yahoo! plus well over a hundred Associate, Liaison, and
Individual members.
For more information, please contact the Unicode
Consortium.
译者: sunboxy
2008年4月4日在加州 Mountain View,U nicode协会很高兴地宣布发布Unicode5 .1。本版本中包含有超过10万个字符,并为世界各地文字处理提供了显着的增加和改善。一些主要特点是:在数据交换上提高安全性,,显着的增补字符为印度及东南亚文字,扩大印度和阿拉伯语文字标识符说明,还改进了泰米尔和其他印度文字的处理,为HTML和其他协议放宽断行的一致性,加强规范化稳定,再加上下面给出的其他内容 。
版本5.1.0数据档案和文件都是最终的并张贴在Unicode的网站。此外,以更新现有的档案,执行者将寻找新的测试数据文件(例如, linebreaking 断行)和新的XML数据文件,并包括了所有的Unicode字符属性。详情请参阅网页上的Unicode 5.1.0在http://www.unicode.org/versions/unicode5.1.0/ 。
Unicode 5.1.0一个主要特点的是允许的表意文字变化序列。这些序列允许日文、中文和朝鲜文标准字符所需的变体。首次登记的集合,来自Adobe系统,现已在http://www.unicode.org/ivd/ 。
Unicode的5.1包含有重大属性改变和行为规范。几个重要属性的定义范围扩大,改善波兰语和葡萄牙语的断行连接符。在 Unicode的文字分割算法,包括句子,词和字符,大大提高泰米尔和其他种语言的处理。Unicode 字符正常化算法,现在确定了稳定的字符串,并为缓冲提供指引。标准化命名序列补充了立陶宛语,及临时命名泰米尔语序列。
Unicode的5.1.0增添新的1624个编码字符。这些增补字符,包括马拉雅拉姆语与缅甸所需要的重要字符,如德语中拉丁大写字符S。
5.1版扩展到支持非洲,印度,印度尼西亚,缅甸和越南等语言。并增设了Cham, Lepcha, Ol Chiki, Rejang, Saurashtra,
Sundanese, 和 Vai 文字。学术支持包括重要的编辑标点符号,以及Carian, Lycian, and
Lydian文字,和Phaistos磁盘符号。其他新的符号集,包括多米诺骨牌,麻将,字典标点符号,和数学补充。这是最新版的Unicode的标准严密对应,作为国际标准化组织/国际电工技术委员会10646:2003加修正1至4
。
在Unicode系统整理算法( uca )
,其核心标准排序所有文本,也正在更新,在同一时间内(见http://www.unicode.org/reports/tr10/
)。uca主要的变化包括涵盖所有的Unicode
5.1字符,收紧一致性,为典型的匹配性,更清晰的定义国际化搜索和匹配,规格参数定制整理,并定义整理折叠。也有一些重要的说明对使用省略(如"Ch "
,在斯洛伐克) ,在整理中。
下一个版本的Unicode系统的本地项目( cldr )也正在Unicode 5.1基础上准备
,现在已经是开放给公众数据意见书(见http://www.unicode.org/cldr/ ) 。
关于Unicode协会
Unicode
协会是一个建立开发,扩大和推广使用的Unicode的标准和相关的全球化标准的非营利性的组织。
协会成员代表着在计算机和信息处理业的广泛的公司和组织。成员名单如下: Adobe公司,苹果电脑,基础技术,
denic例如, Google公司,印度政府,巴基斯坦政府,政府的泰米尔纳德邦,惠普, IBM , justsystems ,微软,甲骨文, SAP , Sun
Microsystems公司,赛贝斯,加州大学伯克利分校,雅虎!再加上百的合作者、联络和个人会员。
如需更多资讯,请联络Unicode协会。
http://blog.csdn.net/fmddlmyy/category/279030.aspx
GB18030有两个版本:GB18030-2000和GB18030-2005。在本文中,没有指明版本的GB18030是指GB18030-2005。本文讨论了以下问题:
- GB2312有682个图形符号,都放在1区。GBK的1区有717个图形符号,5区有 166个图形符号,一共有883个图形符号。GB18030的1区有728个图形符号,5区还是166个符号。那么,GBK的1区在GB2312基础上增 加了哪35个符号?GB18030又增加了哪些符号?
- GBK支持21003个汉字与883个图形符号,一共21886个字符。这21886个字符究竟是哪些字符?这21886个字符的编码在GB18030中有什么变化?
- GB18030是怎样映射Unicode的全部0x110000个码位的?
- GB18030-2000和GB18030-2005在字汇上有什么区别,在编码上有什么区别?
- GB18030-2005的双字节区中有2067个码位被映射到Unicode BMP的PUA。这些码位有什么规律?这些码位中定义了多少字符?其实这2067个码位中只定义了24个字符。
- GBK的21886个字符中有95个字符被映射到Unicode BMP的PUA。在GB18030中这95个字符的编码有哪些变化?哪些字符保持了原来的编码?
- GBK的23940个码位中有多少码位被映射到Unicode BMP的PUA?在GB18030中这些码位的编码有什么变化?
在讨论这些问题前,我们先约定一下码位空间的表示方法。
0 码位空间
0.1 约定
GBK是双字节编码,每个字符用两个字节表示。GB18030是多字节字符集,它的字符可以用一个、两个或四个字节表示。码位空间由各字节的范围确定。例如:GB18030的四字节字符码位空间是:
- 第一字节在0x81~0xFE之间
- 第二字节在0x30~0x39之间
- 第三字节在0x81~0xFE之间
- 第四字节在0x30~0x39之间
为了表述方便,我们用0x81308130~0xFE39FE39表示这个码位空间。也就是说:在本文中0x81308130~0xFE39FE39所指的并不是从0x81308130到0xFE39FE39的连续2097773834(0xFE39FE39-0x81308130+1)个字节。在本文中,0x81308130~0xFE39FE39所指的是编码的各字节在对应范围内的码位空间,这个码位空间的码位数目是:
(0xFE-0x81+1)*(0x39-0x30+1)*(0xFE-0x81+1)*(0x39-0x30+1)=126*10*126*10=1587600
同理,0xB0A1~0xF7FE代表的码位空间是第一字节在0xB0~0xF7之间,第二字节在0xA1~0xFE之间的所有码位。这个码位空间的码位数目是:
(0xF7-0xB0+1)*(0xFE-0xA1+1)=72*94=6768
这个码位空间就是GBK和GB18030的2区,在这6768个码位中定义了6763个字符。
本文用~表示上述码位空间,用-表示一般的范围,即:
- 0xA1A1~0xA9FE 表示第一字节在0xA1到0xA9之间,第二字节在0xA1~0xFE之间的846((0xA9-0xA1+1)*(0xFE-0xA1+1)=9*94)个码位。
- 0xE000-0xF8FF 表示从0xE000-0xF8FF的连续6400(0xF8FF-0xE000+1)个码位。
0.2 习题
读者如果已经理解了上面的约定,请完成下面两个习题:
- 习题一:求码位空间0x8140~0xFE7E的码位数目。
- 习题二:求码位空间0x8180~0xFEFE的码位数目。
0.3 答案
以下是习题0.2的答案:
- 习题一:(0xFE-0x81+1)*(0x7E-0x40+1)=126*63=7938
- 习题二:(0xFE-0x81+1)*(0xFE-0x80+1)=126*127=16002
GB18030双字节字符的码位空间就是0x8140~0xFE7E和0x8180~0xFEFE,双字节字符的码 位数目是7938+16002=23940。0x8140~0xFE7E和0x8180~0xFEFE也是GBK的全部码位空间。GBK在这23940个 码位中定义了21886个字符。
1 GBK回顾
1.1 简介
GBK是双字节编码方案。它的码位空间就是前面所说的0x8140~0xFE7E和0x8180~0xFEFE,一共23940个码位。在这23940个码位上定义了21886个字符,包括21003个汉字和883个图形符号。《Unicode、GB2312、GBK和GB18030中的汉字》详细讨论了这21003个汉字。本文的第3节会讨论GB2312、GBK和GB18030的图形符号。
GBK的码位空间可以划分为以下区域:
| 类别 | 区名 | 码位范围 | 码位数 | 字符数 |
| 符号区 | 1区 | 0xA1A1~0xA9FE | 846 | 717 |
| 5区 | 0xA840~0xA97E和0xA880~0xA9A0 | 192 | 166 | |
| 汉字区 | 2区 | 0xB0A1~0xF7FE | 6768 | 6763 |
| 3区 | 0x8140~0xA07E和0x8180~0xA0FE | 6080 | 6080 | |
| 4区 | 0xAA40~0xFE7E和0xAA80~0xFEA0 | 8160 | 8160 | |
| 用户自定义区 | 用户区1 | 0xAAA1~0xAFFE | 564 | |
| 用户区2 | 0xF8A1~0xFEFE | 658 | ||
| 用户区3 | 0xA140~0xA77E和0xA180~0xA7A0 | 672 |
1.2 GBK字符与Unicode的映射
我制作了一个Excel文件:附件1。这个文件包含3张表格:
- 按照GBK编码排序的GBK全部21886字符码表。这个表格有3列:字符、GBK编码、Unicode编码。
- 按照Unicode编码排序的GBK全部21886字符码表。这个表格有3列:字符、Unicode编码、GBK编码。
- 从
按Unicode编码排序的表格中,很容易找到被映射到PUA(0xE000-0xF8FF)的字符。GBK的21886个字符中有95个字符属于
PUA。第三张表格列出了这95个字符(A列)的GBK编码(B列)、Unicode编码(C列)以及这些字符在GB18030中对应的Unicode编
码(D列)。
其中D列可能不太容易理解,我再解释一下。GB18030是兼容GBK的,所以这些字符的GBK编码和GB18030编码是相同的。 例如的GBK编码和GB18030编码都是0xA8BF。但是在GBK和GB18030中,被映射到不同的Unicode码位。在GBK中, 0xA8BF被映射到Unicode的0xE7C8。在Unicode中,码位0xE7C8是一个PUA码位,保留给用户使用。在GB18030中, 0xA8BF被映射到Unicode的0x01F9。在Unicode中,码位0x01F9属于“拉丁字母扩充-B”这个Block,这个码位定义的字符 是“带抑音符的拉丁文小写字母 N”,字形就是。
1.3 GBK码位与Unicode的映射
GBK的23940个码位定义了21886个字符,还有23940-21886=2054个空闲码位,这2054个 码位都被映射到Unicode的PUA。在设计GBK时,GBK的21886个字符中有95个在Unicode中没有对应字符,所以这95个字符也被映射 到Unicode的PUA。在GBK的23940个码位中,一共有2054+95=2149个码位被映射到PUA,对应的PUA编码是0xE000- 0xE864。0xE000-0xE864就是2149个码位。这2149个码位的分配有以下规律:
| 码位所在区域 | 码位数量 | 映射到的PUA范围 |
| 用户区1:0xAAA1~0xAFFE | 564 | 0xE000-0xE233 |
| 用户区2:0xF8A1~0xFEFE | 658 | 0xE234-0xE4C5 |
| 用户区3:0xA140~0xA77E和A180-A7A0 | 672 | 0xE4C6-0xE765 |
| 符号区(1区和5区)的170个空闲码位 | 170 | 0xE766-0xE80F |
| 2区的5个空闲码位:0xD7FA-0xD7FE | 5 | 0xE810-0xE814 |
| 4区的80个Unicode当时没有定义的字符:FE50-FE7E和FE80-FEA0 | 80 | 0xE815-0xE864 |
附件2包含两张表格:
- 23940个GBK码位与Unicode的映射。两组数据分别按GBK和Unicode排序。
- 2149个映射到PUA的码位,按Unicode顺序排列。
2 GB18030编码
2.1 概述
GB18030是多字节字符集,它的字符可以用一个、两个或四个字节表示。GB18030的码位定义如下:
| 字节数 | 码位空间 | 码位数 | 字符数 |
| 单字节 | 0x00~0x7F | 128 | 128 |
| 双字节 | 0x8140~0xFE7E和0x8180~0xFEFE | 23940 | 21897 |
| 四字节 | 0x81308130~0xFE39FE39 | 1587600 | 54531 |
GB18030有128+23940+1587600=1611668个码位。Unicode的码位数目是0x110000(1114112),少于GB18030。所以,GB18030有足够的空间映射Unicode的所有码位。
GB18030的1611668个码位目前定义了128+21897+54531=76556个字符。Unicode 5.0定义了99089个字符。
2.2 设计思路
GB18030编码可以分为:单字节部分、双字节部分和四字节部分。单字节部分与Unicode的0x00-0x7f完全相同。双字节部分与GBK有两点差异:
- 在1区增加了11个字符。这样1区就有717+11=728个字符。增加的11个字符是:一个欧元符号(0xA2E3)和10个竖排标点符号(0xA6D9-0xA6DF、0xA6EC-0xA6ED和0xA6F3)。
- 原来因为Unicode没有收录而映射到PUA的字符中的部分字符被新版本的Unicode收录,所以将这些字符映射到非PUA的码位。
Unicode的BMP一共有65536个码位。其中代理区(0xD800-0xDFFF)有2048个码位,这 2048个码位是不能定义字符的。GB18030的单字节部分映射了128个码位,GB18030的双字节部分映射了23940个码位。还剩下65536 -2048-128-23940=39420个码位。
GB18030将这39420个码位顺序映射到从0x81308130开始的码位空间。GB18030将 Unicode的16个辅助平面(0x10000-0x10FFFF,一共1048576个码位)顺序映射到从0x90308130开始的码位空间。 GB18030四字节部分中只有这两个区域定义了字符,其它空间都是保留区和自定义区。本文的第3节和第4节还会详细讨论GB18030的双字节和四字节 部分。
GB18030的设计思路可以概括到以下几点:
- 单字节部分与Unicode一致。
- 双字节部分与GBK兼容。适当调整一些字符与Unicode的映射。这些字符原来因为Unicode没有收录而被映射到PUA,现在因为Unicode已经收录而调整到非PUA的Unicode码位。
- 将Unicode BMP部分还没有映射的39420个码位顺序映射到从0x81308130开始的四字节部分。
- 将Unicode BMP以外的16个辅助平面映射到39420个码位顺序映射到从0x90308130开始的四字节部分。
在GB18030目前定义的76556个字符中,只有24个字符被定义到Unicode的PUA区。这24个字符包 括1区的10个竖排标点符号(0xA6D9-0xA6DF、0xA6EC-0xA6ED和0xA6F3)和4区的14个汉字(0xFE51、 0xFE52、0xFE53、0xFE59、0xFE61、0xFE66、0xFE67、0xFE6C、0xFE6D、0xFE76、0xFE7E、 0xFE90、0xFE91、0xFEA0)。4区的14个汉字在Unicode 5.0中其实也可以找到非PUA的编码,详见《Unicode、GB2312、GBK和GB18030中的汉字》。但按照GB18030,它们还是应该映射到PUA码位。
2.3 GB18030-2000和GB18030-2005的区别及以后版本
GB18030-2005与GB18030-2000的编码体系结构是完全相同的。GB18030-2005相对于GB18030-2000主要有以下变化:
- 在四字节字符表中增加CJK统一汉字扩充B和已经在GB13000中编码的我国少数民族文字字符的字形。其实GB18030-2000已经映射了这些码位,但GB18030-2000没有给出这些字符的字形。
- 调整字符的编码。
其中的编码调整比较有意思。的GB18030编码是0xA8BC,在Unicode 5.0的编码是0x1E3F。在GB18030-2000中0xA8BC被映射到Unicode的0xE7C7,因为双字节部分没有映射0x1E3F,所 以它作为BMP的未映射字符被放到四字节部分的0x8135F437。GB18030-2005将0xA8BC映射到0x1E3F,那么Unicode码 位0xE7C7怎么办呢?为了最小化对原来编码的影响,设计者将Unicode码位0xE7C7映射到本来映射0x1E3F的0x8135F437。
GB18030已经映射了Unicode的所有码位,所以不管Unicode怎么变化,GB18030不过就是在现在的码位上增加一些字形而已,编码不会变化。只有现在还映射到PUA的24个字符以后可能会调整到非PUA码位。调整方法应该与的调整方法相同。
2.4 GB18030双字节部分
前面已经介绍过GB18030双字节部分与GBK的区别,本小节再提一些细节。前面也说过,GB18030映射了 Unicode除代理区外的所有码位。所以,Unicode BMP的6400个PUA码位在GB18030中都有对应的码位。GB18030双字节部分映射了2067个PUA码位。
前面说过,GBK映射了2149个PUA码位。现在GB18030双字节部分映射了2067个PUA码位。所以有 2149-2067=82个字符的映射发生了变化。GBK原来有95个字符映射到PUA,其中81个字符在GB18030中被映射到非PUA码位。余下的 14个汉字就是《Unicode、GB2312、GBK和GB18030中的汉字》提到的那14个汉字(0xFE51、0xFE52、0xFE53、0xFE59、0xFE61、0xFE66、0xFE67、0xFE6C、0xFE6D、0xFE76、0xFE7E、0xFE90、0xFE91、0xFEA0)。附件1列出了这些字符的编码变化。82个映射变化的码位,除了这81个外,还有一个就是欧元符号:GB18030编码是0xA2E3,Unicode编码是0x20AC。码位0xA2E3在GBK中被映射到0xE76C,GBK的码位0xA2E3没有定义字符。
GB18030双字节部分与Unicode的映射没有规律,只能通过查表方法映射。
2.5 GB18030四字节部分
GB18030四字节部分的字符可以见GB18030-2005的“表3 四字节部分的码位安排”,一共54531个字符。GB18030四字节部分的码位可以见GB18030-2005的“7.3 四字节部分字符的排列顺序”。其中定义字符的只有两个区域:
- GB18030用码位0x81308130~0x8439FE39共50400个码位映射该标准单字节和双字节部分没有映射过的39420个Unicode BMP码位。
- GB18030用码位0x90308130~0xE339FE39共1058400个码位映射Unicode 16个辅助平面(平面1到平面16)的65536*16=1048576个码位。
为了叙述方便,本文将0x81308130~0x8439FE39称作“BMP扩展部分”,将 0x90308130~0xE339FE39称作“辅助平面部分”。GB18030四字节部分的码位空间是0x81308130~0xFE39FE39。 第二字节有(0x39-0x30+1)=10个可能值。第三字节有(0xFE-0x81+1)=126个可能值。第四字节也是(0x39-0x30+1) =10个可能值。为了方便下面的演算,本文为这个码位空间定义几个名词:
- 我们将四字节码位空间中第一字节相同的区域称作一级区。每个一级区有12600个码位,即:10*126*10。
- 我们将四字节码位空间中第一字节和第二字节相同的区域称作二级区。每个二级区有1260个码位,即:126*10。
- 我们将四字节码位空间中前三个字节相同的区域称作三级区,每个三级区有10个码位。
四字节部分一共有(0xFE-0x81+1)=126个一级区。BMP扩展部分有4个一级区。辅助平面部分有84个一级区。还有38个一级区是保留区或自定义区。
2.5.1 BMP扩展部分
BMP扩展部分占据四字节部分开头的4个一级区,一共有4*12600=50400个码位。这段空间的 Unicode映射说起来还是很简单的,就是顺序映射单字节、双字节没有映射过的BMP码位。这些映射关系在GB18030-2000中确定下来。以后的 调整(例如)只是个别字符,不会影响其它字符的位置。但是因为双字节字符已经映射过的BMP码位没有什么规律,所以造成BMP扩展部分的Unicode 映射也不能用公式换算,还是要查表解决。
显然这50400个码位中只用到了39420个码位,其余码位都是保留的。出于好玩,我们来计算一下最后一个非保留码位(0xFFFF)的位置,计算过程如下:
- m1=(39420-1)/12600=3
- n1=(39420-1)%12600=1619
- m2=n1/1260=1619/1260=1
- n2=n1%1260=1619%1260=359
- m3=n2/10=359/10=35
- n3=n2%10=359%10=9
- 第一字节的位置是:0x81+m1=0x81+3=0x84
- 第二字节的位置是:0x30+m2=0x30+1=0x31
- 第三字节的位置是:0x81+m3=0x81+35=0xA4
- 第四字节的位置是:0x30+n3=0x30+9=0x39
所以Unicode编码0xFFFF映射的GB18030码位是0x8431A439。在BMP扩展部分中,0x8431A439以后的码位都是保留码位。上述计算中,/表示整除(例如5/3=1),%表示取余(例如5%3=2)。
2.5.2 辅助平面部分
辅助平面部分用84个一级区(0x90308130~0xE339FE39)直接映射Unicode的16个辅助平面。这部分映射是可以直接用公式计算的。让我们看看怎么计算。
- 从Unicode编码到GB18030编码的映射方法如下:
- U=Unicode编码-0x10000
- m1=U/12600
- n1=U%12600
- m2=n1/1260
- n2=n1%1260
- m3=n2/10
- n3=n2%10
- 第一字节b1=m1+0x90
- 第二字节b2=m2+0x30
- 第三字节b3=m3+0x81
- 第四字节b4=n3+0x30
- 将m1放在B12,B12=INT((HEX2DEC(A12)-65536)/12600)
- 将n1放在C12,C12=MOD((HEX2DEC(A12)-65536),12600)
- 将m2放在D12,D12=INT(C12/1260)
- 将n2放在E12,E12=MOD(C12,1260)
- 将m3放在F12,F12=INT(E12/10)
- 将n3放在G12,G12=MOD(E12,10)
- 将第一字节放在H12,H12=DEC2HEX(B12+144)
- 将第二字节放在I12,I12=DEC2HEX(D12+48)
- 将第三字节放在J12,J12=DEC2HEX(F12+129)
- 将第四字节放在K12,K12=DEC2HEX(G12+48)
- 从GB18030编码到Unicode编码的映射方法如下:
- 设GB18030编码的四个字节依次为:b1、b2、b3、b4,则
Unicode编码=0x10000+(b1-0x90)*12600+(b2-0x30)*1260+(b3-0x81)*10+b4-0x30
- E4 = =DEC2HEX((HEX2DEC(A4)-144)*12600+(HEX2DEC(B4)-48)*1260+(HEX2DEC(C4)-129)*10+(HEX2DEC(D4)-48)+65536)
- 设GB18030编码的四个字节依次为:b1、b2、b3、b4,则
2.6 GB18030和Unicode的映射表
附件3给出了GB18030和Unicode的映射表。这个Excel文件是在网友谢振斌先生的映射表基础上制作的,包含3张表格:
- 双字节部分23940个码位与Unicode的映射。两组数据分别按GB18030和Unicode排序。
- BMP扩展部分39420个码位与Unicode的映射。两组数据分别按GB18030和Unicode排序。
- 辅助平面部分,GB18030编码和Unicode编码的映射公式。
3 GB2312、GBK和GB18030中的图形符号
在研究GB18030编码的过程中,我整理了GB2312、GBK和GB18030在1区和5区的图形符号,制作了附件4。这个Excel文件包含3张表格:
- GB2312的1区字符表。GBK和GB18030的1区、5区字符表。用不同颜色标注了GBK增加的35个字符和GB18030增加的11个字符。
- GB2312 1区682个符号的编码。
- GBK 1区717个符号的编码。
结束语
通过本文的介绍,读者可以回答开头的问题了吗?
无论是Windows XP还是Vista,中文(中国)区域对应的默认代码页还是GBK。我们只能设置区域,并不能设置区域对应的默认代码页。所以在Windows世界,只要 微软不愿意,GB18030就只是一张普通的代码页。目前的简体中文文档使用的编码主要是Unicode和GBK,应该没有什么文档会用GB18030保 存。本文只是出于程序员的好奇而对GB18030编码所作的一些研究,希望能对同样好奇的读者有所助益。
GB18030有两个版本:GB18030-2000和GB18030-2005。GB18030-2000是GBK的取 代版本,它的主要特点是在GBK基础上增加了CJK统一汉字扩充A的汉字。GB18030-2005的主要特点是在GB18030-2000基础上增加了 CJK统一汉字扩充B的汉字。本文数一数GB18030中的汉字,也顺便看看其它标准中的汉字。
1 Unicode中的汉字
在Unicode 5.0的99089个字符中,有71226个字符与汉字有关。它们的分布如下:
| Block名称 | 开始码位 | 结束码位 | 字符数 | |
| CJK统一汉字 | 4E00 | 9FBB | 20924 | |
| CJK统一汉字扩充A | 3400 | 4DB5 | 6582 | |
| CJK统一汉字扩充B | 20000 | 2A6D6 | 42711 | |
| CJK兼容汉字 | F900 | FA2D | 302 | |
| CJK兼容汉字 | FA30 | FA6A | 59 | |
| CJK兼容汉字 | FA70 | FAD9 | 106 | |
| CJK兼容汉字补充 | 2F800 | 2FA1D | 542 |
如果不算兼容汉字,Unicode目前支持的汉字总数是20924+6582+42711=70217。
这里有一个细节。在早期的Unicode版本中,CJK统一汉字区的范围是0x4E00-0x9FA5,也就是我们经常提到的20902个汉字。当前版本的Unicode增加了22个字符,码位是0x9FA6-0x9FBB。它们是:
![]()
那么GB18030是否支持这22个字符?后面还会讨论。
2 GB2312
1980年的GB2312一共收录了7445个字符,包括6763个汉字和682个其它符号。汉字区的内码范围高字节从B0-F7,低字节从A1-FE,占用的码位是72*94=6768。其中有5个空位是D7FA-D7FE。
这6763个汉字在Unicode中不是连续的,分布在CJK统一汉字字符区(0x4E00-0x9FA5)的20902个汉字中。
3 GBK
1995年的汉字扩展规范GBK1.0收录了21886个符号,包括21003个汉字和883个其它符号。
这21003汉字包括CJK统一汉字区的20902个汉字。余下的101个汉字包括:
- 增补汉字和部首80个,包括28个部首和52个汉字。GBK编码是从FE50-FE7E,FE80-FEA0。下图标注了Unicode编码。

在 制定GBK时,Unicode中还没有这些字符,所以使用了专用区的码位,这80个字符的码位是0xE815-0xE864。后来,Unicode将52 个汉字收录到“CJK统一汉字扩充A”。28个部首中有14个部首被收录到“CJK部首补充区”。所以在上图中,这些字符都有两个Unicode编码。
上图中淡黄色背景的8个部首被收录到“CJK统一汉字区”的新增区域,即前面提到的0x9FA6-0x9FBB。还有6个淡灰色背景的部首被Unicode收录到“CJK统一汉字扩充B”(网友slt指正)。
请 注意,淡黄色和淡灰色的14个字符按照GB18030还是应该映射到PUA码位。这14个字符与非PUA码位的映射关系只是网友找出来的,不是标准规定 的。如果按照GBK编码,这80个字符应该全部映射到PUA码位。GB18030将其中66个字符映射到了非PUA码位。不过在Windows中,简体中 文区域的默认代码页还是GBK,不是GB18030。
- CJK兼容汉字区挑选出来的21个汉字。见下表:
汉字 GBK编码 Unicode编码 郎 FD9C F92C 凉 FD9D F979 秊 FD9E F995 裏 FD9F F9E7 隣 FDA0 F9F1 兀 FE40 FA0C 嗀 FE41 FA0D 﨎 FE42 FA0E 﨏 FE43 FA0F 﨑 FE44 FA11 﨓 FE45 FA13 﨔 FE46 FA14 礼 FE47 FA18 﨟 FE48 FA1F 蘒 FE49 FA20 﨡 FE4A FA21 﨣 FE4B FA23 﨤 FE4C FA24 﨧 FE4D FA27 﨨 FE4E FA28 﨩 FE4F FA29
4 GB18030-2000
4.1 字汇
GB18030-2000的字汇部分是这样写的:
本标准收录的字符分别以单字节、双字节和四字节编码。5.1 单字节部分
本标准中,单字节的部分收录了GB 11383的0x00到0x7F全部128个字符及单字节编码的欧元符号。
5.2 双字节部分
本标准中,双字节的部分收录内容如下:
GB 13000.1的全部CJK统一汉字字符。
GB 13000.1的CJK兼容区挑选出来的21个汉字。
GB 13000.1中收录而GB 2312未收录的我国台湾地区使用的图形字符139个。
GB 13000.1收录的其它字符31个。
GB 2312中的非汉字符号。
GB 12345 的竖排标点符号19个。
GB 2312未收录的10个小写罗马数字。
GB 2312未收录的带音调的汉语拼音字母5个以及ɑ 和ɡ 。
汉字数字“〇”。
表意文字描述符13个。
增补汉字和部首/构件80个。
双字节编码的欧元符号。
5.3 四字节部分
本标准的四字节的部分,收录了上述双字节字符之外的,包括CJK统一汉字扩充A在内的GB 13000.1 中的全部字符。
4.2 汉字
如下表所示,GB18030-2000收录了27533个汉字:
| 类别 | 码位范围 | 码位数 | 字符数 | 字符类型 |
| 双字节部分 | 第一字节 0xB0-0xF7 第二字节 0xA1-0xFE |
6768 | 6763 | 汉字 |
| 第一字节0x81-0xA0 第二字节0x40-0xFE |
6080 | 6080 | 汉字 | |
| 第一字节0xAA-0xFE 第二字节0x40-0xA0 |
8160 | 8160 | 汉字 | |
| 四字节部分 | 第一字节0x81-0x82 第二字节0x30-0x39 第三字节0x81-0xFE 第四字节0x30-0x39 |
6530 | 6530 | CJK统一汉字扩充A |
27533就是6763+6080+8160+6530。双字节部分的6763+6080+8160=21003个汉字就是GBK的21003个汉字。
在Unicode中,CJK统一汉字扩充A有6582个汉字,为什么这里只有6530个汉字?
这是因为在GBK时代,双字节部分已经收录过CJK统一汉字扩充A的52个汉字,所以还余6530个汉字。
5 GB18030-2005
5.1 字汇
GB18030-2005的字汇部分是这样写的:
本标准收录的字符分别以单字节、双字节或四字节编码。5.1 单字节部分
本标准中,单字节的部分收录了GB/T 11383-1989的0x00到0x7F全部128个字符。
5.2 双字节部分
本标准中,双字节的部分收录内容如下:
GB 13000.1-1993的全部CJK统一汉字字符。见附录A。
GB 13000.1-1993的CJK兼容区挑选出来的21个汉字。见附录A。
GB 13000.1-1993中收录而GB 2312未收录的我国台湾地区使用的图形字符139个。见附录A。
GB 13000.1-1993收录的其它字符31个。见附录A。
GB 2312中的非汉字符号。见附录A。
GB 12345 的竖排标点符号19个。见附录A。
GB 2312未收录的10个小写罗马数字。见附录A。
GB 2312未收录的带音调的汉语拼音字母5个以及ɑ 和ɡ 。见附录A。
汉字数字“〇”。 见附录A。
表意文字描述符13个。见附录A和附录B。
对GB 13000.1-1993增补的汉字和部首/构件80个。见附录A和附录C。
双字节编码的欧元符号。见附录A。
5.3 四字节部分
本标准的四字节的部分,收录了上述双字节字符之外的,GB 13000的CJK统一汉字扩充A、CJK统一汉字扩充B和已经在GB13000中编码的我国少数民族文字的字符。见附录D。
GB18030-2005最主要的变化是增加了CJK统一汉字扩充B。它还去掉了单字节编码的欧元符号(0x80)。
5.2 汉字
如下表所示,GB18030-2005收录了70244个汉字:
| 类别 | 码位范围 | 码位数 | 字符数 | 字符类型 |
| 双字节部分 | 第一字节 0xB0-0xF7 第二字节 0xA1-0xFE |
6768 | 6763 | 汉字 |
| 第一字节0x81-0xA0 第二字节0x40-0xFE |
6080 | 6080 | 汉字 | |
| 第一字节0xAA-0xFE 第二字节0x40-0xA0 |
8160 | 8160 | 汉字 | |
| 四字节部分 | 第一字节0x81-0x82 第二字节0x30-0x39 第三字节0x81-0xFE 第四字节0x30-0x39 |
6530 | 6530 | CJK统一汉字扩充A |
| 第一字节0x95-0x98 第二字节0x30-0x39 第三字节0x81-0xFE 第四字节0x30-0x39 |
42711 | 42711 | CJK统一汉字扩充B |
70244就是6763+6080+8160+6530+42711。
6 结束语
GB2312有6763个汉字,GBK有21003个汉字,GB18030-2000有27533个汉字,GB18030-2005有70244个汉字。
Unicode 5.0中,如果不算兼容区,目前有70217个汉字。让我们比较一下Unicode的70217汉字和GB18030-2005中的70244汉字:
| GB18030-2005 | Unicode 5.0 | 对应的Unicode编码 |
| CJK统一汉字的20902汉字 | CJK统一汉字的20902汉字 | 0x4E00-0x9FA5 |
| CJK统一汉字扩充A的6582汉字 | CJK统一汉字扩充A的6582汉字 | 0x3400-0x4DB5 |
| CJK统一汉字扩充B的42711汉字 | CJK统一汉字扩充B的42711汉字 | 0x20000-0x2A6D6 |
| CJK部首补充区的14个部首 | 未计入 | 2E81, 2E84, 2E88, 2E8B, 2E8C, 2E97, 2EA7, 2EAA, 2EAE, 2EB3, 2EB6, 2EB7, 2EBB, 2ECA |
| CJK兼容汉字区的21个汉字 | 未计入 | F92C, F979, F995, F9E7, F9F1, FA0C, FA0D, FA0E, FA0F, FA11, FA13, FA14, FA18, FA1F, FA20, FA21, FA23, FA24, FA27, FA28, FA29 |
| CJK统一汉字区新增了这8个字符 | 0x9FB4-0x9FBB | |
| 未计入 | CJK统一汉字区新增的14个字符 | 0x9FA6-0x9FB3 |
因为GB18030映射了Unicode的所有码位,所以CJK统一汉字区新增的0x9FA6-0x9FB3这14个字符在GB18030中都有对应的码位。不过GB18030没有明确收录这些字符。
附录1 GB18030的汉字编码表
我整理了GB18030的汉字编码表,需要的朋友可以下载。以下是其中的简要说明:
简要说明将表1(21003)和表2(6530)合起来就是GB18030-2000要求的27533个汉字
将表1(21003)、表2(6530)和表3(42711)合起来就是GB18030-2005要求的70244个汉字
Unicode的扩充A本来有6582个汉字,因为GB18030的双字节区已经收录过Unicode扩充A的52个汉字,所以GB18030四字节区扩充A只有6530个汉字。表4列出了这52个汉字。
GBK增补的80个字符本来是放在PUA区的。后来又被Unicode收录。所以既可以用PUA区的编码表示,也可以用非PUA编码表示。如下表所示。
先从ASCII说起。ASCII是用来表示英文字符的一种编码规范,每个ASCII字符占用1个字节(8bits)
因此,ASCII编码可以表示的最大字符数是256,其实英文字符并没有那么多,一般只用前128个(最高位为0),其中包括了控制字符、数字、大小写字母和其他一些符号 。
而最高位为1的另128个字符被成为“扩展ASCII”,一般用来存放英文的制表符、部分音标字符等等的一些其他符号
这种字符编码规范显然用来处理英文没有什么问题 。(实际上也可以用来处理法文、德文等一些其他的西欧字符,但是不能和英文通用),但是面对中文、阿拉伯文之类复杂的文字,255个字符显然不够用
于是,各个国家纷纷制定了自己的文字编码规范,其中中文的文字编码规范叫做“GB2312-80”,它是和ASCII兼容的一种编码规范,其实就是利用扩展ASCII没有真正标准化这一点,把一个中文字符用两个扩展ASCII字符来表示。
但 是这个方法有问题,最大的问题就是,中文文字没有真正属于自己的编码,因为扩展ASCII码虽然没有真正的标准化,但是PC里的ASCII码还是有一个事 实标准的(存放着英文制表符),所以很多软件利用这些符号来画表格。这样的软件用到中文系统中,这些表格符就会被误认作中文字,破坏版面。而且,统计中英 文混合字符串中的字数,也是比较复杂的,我们必须判断一个ASCII码是否扩展,以及它的下一个ASCII是否扩展,然后才“猜”那可能是一个中文字 。
总之当时处理中文是很痛苦的。而更痛苦的是GB2312是国家标准,台湾当时有一个Big5编码标准,很多编码和GB是相同的,所以……,嘿嘿。
这 时候,我们就知道,要真正解决中文问题,不能从扩展ASCII的角度入手,也不能仅靠中国一家来解决。而必须有一个全新的编码系统,这个系统要可以将中 文、英文、法文、德文……等等所有的文字统一起来考虑,为每个文字都分配一个单独的编码,这样才不会有上面那种现象出现。
于是,Unicode诞生了。
Unicode有两套标准,一套叫UCS-2(Unicode-16),用2个字节为字符编码,另一套叫UCS-4(Unicode-32),用4个字节为字符编码。
以目前常用的UCS-2为例,它可以表示的字符数为2^16=65535,基本上可以容纳所有的欧美字符和绝大部分的亚洲字符 。
UTF-8的问题后面会提到 。
在Unicode里,所有的字符被一视同仁。汉字不再使用“两个扩展ASCII”,而是使用“1个Unicode”,注意,现在的汉字是“一个字符”了,于是,拆字、统计字数这些问题也就自然而然的解决了 。
但是,这个世界不是理想的,不可能在一夜之间所有的系统都使用Unicode来处理字符,所以Unicode在诞生之日,就必须考虑一个严峻的问题:和ASCII字符集之间的不兼容问题。
我们知道,ASCII字符是单个字节的,比如“A”的ASCII是65。而Unicode是双字节的,比如“A”的Unicode是0065,这就造成了一个非常大的问题:以前处理ASCII的那套机制不能被用来处理Unicode了 。
另一个更加严重的问题是,C语言使用'\0'作为字符串结尾,而Unicode里恰恰有很多字符都有一个字节为0,这样一来,C语言的字符串函数将无法正常处理Unicode,除非把世界上所有用C写的程序以及他们所用的函数库全部换掉 。
于是,比Unicode更伟大的东东诞生了,之所以说它更伟大是因为它让Unicode不再存在于纸上,而是真实的存在于我们大家的电脑中。那就是:UTF 。
UTF= UCS Transformation Format UCS转换格式
它是将Unicode编码规则和计算机的实际编码对应起来的一个规则。现在流行的UTF有2种:UTF-8和UTF-16 。
其中UTF-16和上面提到的Unicode本身的编码规范是一致的,这里不多说了。而UTF-8不同,它定义了一种“区间规则”,这种规则可以和ASCII编码保持最大程度的兼容 。
UTF-8有点类似于Haffman编码,它将Unicode编码为00000000-0000007F的字符,用单个字节来表示;
00000080-000007FF的字符用两个字节表示
00000800-0000FFFF的字符用3字节表示
因为目前为止Unicode-16规范没有指定FFFF以上的字符,所以UTF-8最多是使用3个字节来表示一个字符。但理论上来说,UTF-8最多需要用6字节表示一个字符。
在UTF-8里,英文字符仍然跟ASCII编码一样,因此原先的函数库可以继续使用。而中文的编码范围是在0080-07FF之间,因此是2个字节表示(但这两个字节和GB编码的两个字节是不同的),用专门的Unicode处理类可以对UTF编码进行处理。
下面说说中文的问题。
由于历史的原因,在Unicode之前,一共存在过3套中文编码标准。
GB2312-80,是中国大陆使用的国家标准,其中一共编码了6763个常用简体汉字。Big5,是台湾使用的编码标准,编码了台湾使用的繁体汉字,大概有8千多个。HKSCS,是中国香港使用的编码标准,字体也是繁体,但跟Big5有所不同。
这3套编码标准都采用了两个扩展ASCII的方法,因此,几套编码互不兼容,而且编码区间也各有不同
因为其不兼容性,在同一个系统中同时显示GB和Big5基本上是不可能的。当时的南极星、RichWin等等软件,在自动识别中文编码、自动显示正确编码方面都做了很多努力 。
他们用了怎样的技术我就不得而知了,我知道好像南极星曾经以同屏显示繁简中文为卖点。
后来,由于各方面的原因,国际上又制定了针对中文的统一字符集GBK和GB18030,其中GBK已经在Windows、Linux等多种操作系统中被实现。
GBK兼容GB2312,并增加了大量不常用汉字,还加入了几乎所有的Big5中的繁体汉字。但是GBK中的繁体汉字和Big5中的几乎不兼容。
GB18030相当于是GBK的超集,比GBK包含的字符更多。据我所知目前还没有操作系统直接支持GB18030。
谈谈Unicode编码,简要解释UCS、UTF、BMP、BOM等名词
这是一篇程序员写给程序员的趣味读物。所谓趣味是指可以比较轻松地了解一些原来不清楚的概念,增进知识,类似于打RPG游戏的升级。整理这篇文章的动机是两个问题:
问题一:
使用Windows记事本的“另存为”,可以在GBK、Unicode、Unicode big endian和UTF-8这几种编码方式间相互转换。同样是txt文件,Windows是怎样识别编码方式的呢?
我 很早前就发现Unicode、Unicode big endian和UTF-8编码的txt文件的开头会多出几个字节,分别是FF、FE (Unicode),FE、FF(Unicode big endian),EF、BB、BF(UTF-8)。但这些标记是基于什么标准呢?
问题二:
最 近在网上看到一个ConvertUTF.c,实现了UTF-32、UTF-16和UTF-8这三种编码方式的相互转换。对于Unicode(UCS2)、 GBK、UTF-8这些编码方式,我原来就了解。但这个程序让我有些糊涂,想不起来UTF-16和UCS2有什么关系。
查了查相关资料,总算将这些问题弄清楚了,顺带也了解了一些Unicode的细节。写成一篇文章,送给有过类似疑问的朋友。本文在写作时尽量做到通俗易懂,但要求读者知道什么是字节,什么是十六进制。
0、big endian和little endian
big endian 和little endian是CPU处理多字节数的不同方式。例如“汉”字的Unicode编码是6C49。那么写到文件里时,究竟是将6C写在前面, 还是将49写在前面?如果将6C写在前面,就是big endian。还是将49写在前面,就是little endian。
“endian”这个词出自《格列佛游记》。小人国的内战就源于吃鸡蛋时是究竟从大头(Big-Endian)敲开还是从小头(Little-Endian)敲开,由此曾发生过六次叛乱,其中一个皇帝送了命,另一个丢了王位。
我们一般将endian翻译成“字节序”,将big endian和little endian称作“大尾”和“小尾”。
1、字符编码、内码,顺带介绍汉字编码
字符必须编码后才能被计算机处理。计算机使用的缺省编码方式就是计算机的内码。早期的计算机使用7位的ASCII编码,为了处理汉字,程序员设计了用于简体中文的GB2312和用于繁体中文的big5。
GB2312(1980年)一共收录了7445个字符,包括6763个汉字和682个其它符号。汉字区的内码范围高字节从B0-F7,低字节从A1-FE,占用的码位是72*94=6768。其中有5个空位是D7FA-D7FE。
GB2312 支持的汉字太少。1995年的汉字扩展规范GBK1.0收录了21886个符号,它分为汉字区和图形符号区。汉字区包括21003个字符。2000年的 GB18030是取代GBK1.0的正式国家标准。该标准收录了27484个汉字,同时还收录了藏文、蒙文、维吾尔文等主要的少数民族文字。现在的PC平 台必须支持GB18030,对嵌入式产品暂不作要求。所以手机、MP3一般只支持GB2312。
从ASCII、GB2312、GBK到 GB18030,这些编码方法是向下兼容的,即同一个字符在这些方案中总是有相同的编码,后面的标准支持更多的字符。在这些编码中,英文和中文可以统一地 处理。区分中文编码的方法是高字节的最高位不为0。按照程序员的称呼,GB2312、GBK到GB18030都属于双字节字符集 (DBCS)。
有的中文Windows的缺省内码还是GBK,可以通过GB18030升级包升级到GB18030。不过GB18030相对GBK增加的字符,普通人是很难用到的,通常我们还是用GBK指代中文Windows内码。
这里还有一些细节:
GB2312的原文还是区位码,从区位码到内码,需要在高字节和低字节上分别加上A0。
在DBCS中,GB内码的存储格式始终是big endian,即高位在前。
GB2312 的两个字节的最高位都是1。但符合这个条件的码位只有128*128=16384个。所以GBK和GB18030的低字节最高位都可能不是1。不过这不影 响DBCS字符流的解析:在读取DBCS字符流时,只要遇到高位为1的字节,就可以将下两个字节作为一个双字节编码,而不用管低字节的高位是什么。
2、Unicode、UCS和UTF
前面提到从ASCII、GB2312、GBK到GB18030的编码方法是向下兼容的。而Unicode只与ASCII兼容(更准确地说,是与ISO-8859-1兼容),与GB码不兼容。例如“汉”字的Unicode编码是6C49,而GB码是BABA。
Unicode 也是一种字符编码方法,不过它是由国际组织设计,可以容纳全世界所有语言文字的编码方案。Unicode的学名是"Universal Multiple -Octet Coded Character Set",简称为UCS。UCS可以看作是"Unicode Character Set"的缩写。
根据维基百科全书(http://zh.wikipedia.org/wiki/)的记载:历史上存在两个试图独立设计Unicode的组织,即国际标准化组织(ISO)和一个软件制造商的协会(unicode.org)。ISO开发了ISO 10646项目,Unicode协会开发了Unicode项目。
在1991年前后,双方都认识到世界不需要两个不兼容的字符集。于是它们开始合并双方的工作成果,并为创立一个单一编码表而协同工作。从Unicode2.0开始,Unicode项目采用了与ISO 10646-1相同的字库和字码。
目前两个项目仍都存在,并独立地公布各自的标准。Unicode协会现在的最新版本是2005年的Unicode 4.1.0。ISO的最新标准是10646-3:2003。
UCS规定了怎么用多个字节表示各种文字。怎样传输这些编码,是由UTF(UCS Transformation Format)规范规定的,常见的UTF规范包括UTF-8、UTF-7、UTF-16。
IETF 的RFC2781和RFC3629以RFC的一贯风格,清晰、明快又不失严谨地描述了UTF-16和UTF-8的编码方法。我总是记不得IETF是 Internet Engineering Task Force的缩写。但IETF负责维护的RFC是Internet上一切规范的基础。
3、UCS-2、UCS-4、BMP
UCS有两种格式:UCS-2和UCS-4。顾名思义,UCS-2就是用两个字节编码,UCS-4就是用4个字节(实际上只用了31位,最高位必须为0)编码。下面让我们做一些简单的数学游戏:
UCS-2有2^16=65536个码位,UCS-4有2^31=2147483648个码位。
UCS -4根据最高位为0的最高字节分成2^7=128个group。每个group再根据次高字节分为256个plane。每个plane根据第3个字节分为 256行 (rows),每行包含256个cells。当然同一行的cells只是最后一个字节不同,其余都相同。
group 0的plane 0被称作Basic Multilingual Plane, 即BMP。或者说UCS-4中,高两个字节为0的码位被称作BMP。
将UCS-4的BMP去掉前面的两个零字节就得到了UCS-2。在UCS-2的两个字节前加上两个零字节,就得到了UCS-4的BMP。而目前的UCS-4规范中还没有任何字符被分配在BMP之外。
4、UTF编码
UTF-8就是以8位为单元对UCS进行编码。从UCS-2到UTF-8的编码方式如下:
UCS-2编码(16进制) UTF-8 字节流(二进制)
0000 - 007F 0xxxxxxx
0080 - 07FF 110xxxxx 10xxxxxx
0800 - FFFF 1110xxxx 10xxxxxx 10xxxxxx
例 如“汉”字的Unicode编码是6C49。6C49在0800-FFFF之间,所以肯定要用3字节模板了: 1110xxxx 10xxxxxx 10xxxxxx。将6C49写成二进制是:0110 110001 001001, 用这个比特流依次代替模板中 的x,得到:11100110 10110001 10001001,即E6 B1 89。
读者可以用记事本测试一下我们的编码是否正确。
UTF -16以16位为单元对UCS进行编码。对于小于0x10000的UCS码,UTF-16编码就等于UCS码对应的16位无符号整数。对于不小于 0x10000的UCS码,定义了一个算法。不过由于实际使用的UCS2,或者UCS4的BMP必然小于0x10000,所以就目前而言,可以认为UTF -16和UCS-2基本相同。但UCS-2只是一个编码方案,UTF-16却要用于实际的传输,所以就不得不考虑字节序的问题。
5、UTF的字节序和BOM
UTF -8以字节为编码单元,没有字节序的问题。UTF-16以两个字节为编码单元,在解释一个UTF-16文本前,首先要弄清楚每个编码单元的字节序。例如收 到一个“奎”的Unicode编码是594E,“乙”的Unicode编码是4E59。如果我们收到UTF-16字节流“594E”,那么这是“奎”还是 “乙”?
Unicode规范中推荐的标记字节顺序的方法是BOM。BOM不是“Bill Of Material”的BOM表,而是Byte Order Mark。BOM是一个有点小聪明的想法:
在UCS 编码中有一个叫做"ZERO WIDTH NO-BREAK SPACE"的字符,它的编码是FEFF。而FFFE在UCS中是不存在的字符,所以不应该 出现在实际传输中。UCS规范建议我们在传输字节流前,先传输字符"ZERO WIDTH NO-BREAK SPACE"。
这样如果接收者收到FEFF,就表明这个字节流是Big-Endian的;如果收到FFFE,就表明这个字节流是Little-Endian的。因此字符"ZERO WIDTH NO-BREAK SPACE"又被称作BOM。
UTF -8不需要BOM来表明字节顺序,但可以用BOM来表明编码方式。字符"ZERO WIDTH NO-BREAK SPACE"的UTF-8编码是 EF BB BF(读者可以用我们前面介绍的编码方法验证一下)。所以如果接收者收到以EF BB BF开头的字节流,就知道这是UTF-8编码了。
Windows就是使用BOM来标记文本文件的编码方式的

