Unicode与ISO10646(作者:曾士熊)
一、缘起
1960年代初期,美国国会图书馆(Library of Congress, LC)的
Henriette Avram等人开始研拟机读编目格式,同时James Agenboard
等人也制订了英文的字符集和交换码,以做为美国图书馆界书目交
换的共同标准。LC交换码随后发展成为美国的国家标准ASCII(American
Standard Codefor Information Interchange),而且还进一步演
变成世界性的计算机字符编码标准ISO646(其全名为7-bit coded
character set for information interchange)。时至今日,虽然
一个字节(byte)的长度已经从7个位(bit)增加为8个位,
ASCII和ISO646 仍然是计算机与网络世界里要的奠基标准。
依ASCII和ISO646的规定,7个位所能提供的128个编码位置(编
码范围为0~127)被区分为两部分:94个图形字符码和34个控制字
元码。图形字符包括52个大小写英文字母﹑10个阿拉伯数字﹑9个标
点符号﹑6个括号,以及17个其它符号,编码范围从33到126。控制
字符则包括10个传输控制字符、6个版面调整字符、4个设备控制字
元、 4个信息分隔字符和10个特殊控制字符,其编码为0~32和127。
当计算机或网络设备收到一连串的位信号时,通常会一边接收一边
切分为字节(即每8个位一切),并且立刻分辨刚收到的位
组究竟是控制字符码还是图形字符码。若是属收讯设备相关的控制
字符时(例如传输控制、编码为7的BELL等字符),当计算机或网络
设备会截留该字符并立即做出对应动作(例如BELL字符会驱使收讯
设备叫一声),否则不予处理而传送给后续设备。换言之,计算机和
网络设备会吃掉位串里的特定控制字符码。
随着计算机功能的日趋强大与价格的日趋便宜,其应用领域也越来
越广。但是随之而来的各种编码需求,却使得单一字节的编码方
式,因编码空间太小,变得不足以因应各种应用程序的需求。中文
字、排版系统的标志符号、非英语拼音字母和图形符号等的编码,
需要使用2或多个字节来编码。同时,为了预防这些多字节字符
码被计算机或网络设备「吃掉」其中的某个字节,编码时必须避开
每个字节的0~32和127这34个句柄。这种做法严重浪费编码空
间,就多字节扩充编码的国际标准ISO2022而言,两个8位的位
元组只能提供最多188个控制字符和35,344个文字形符号的编码空间,
共计35,532个编码位置,但是16个位的编码空间事实上高达65,536。
两者相比较,ISO2022的16位编码只能达到最大编码空间的54%,
显得利用率很差。同时在应用层次的编码,由于厂商众多又缺乏共
识,往往你编你的码、我编我的码,其后果则是引发万码奔腾的乱
象。
为容纳全世界各种语言的字符和符号,ISO的一些会员国于1984年
发起制定新的国际字符集编码标准。新标准由工作小组ISO/IEC
JTC1/SC2/WG2(注1)负责拟订(以下简称WG2),最后定案的标准
命名为"Universal Multiple-Octet Coded Character Set"
(简称UCS),其编号则订为ISO/IEC 10646。依WG2原来的规划,
ISO10646的编码结构系沿袭ISO2022八位延伸编码结构以避开C0和
C1两个句柄区(注2),但打破每个字符码里的所有字节的bit-8
(即最左边的位,其值为28=128)必须都设为0或是都设为1的限制,
以提高编码空间的使用率。同时,为了能有足够位置以容纳全世界各
种语言的字符和符号,以及为了配合微处理器以8、16、32甚或64个
位为一个运算处理单位的趋势,ISO10646的字符码长度被规定为
定长的4个八位(octet)。
ISO10646草案初稿一经公布,其编码结构立即遭到美国部份计算机
业者的反对。1988年初,美国Xerox公司的Joe Becker倡议以新的编
码结构,另外编订世界性字符编码标准:将计算机字符集编码的基本
单位由现行的7或8个位一举扩充为16个位,并且充分利用65,536
个编码位置以容纳全世界各种语言的字符和常用符号。新的字符集
编码标准被命名为"Unicode"(注3)。一群来自Xerox公司和Apple
公司的工程师组成工作小组,负责Unicode的原始设计工作。1991年
元月,十多家计算机硬软件、网络和信息服务业者,包括:IBM、DEC、
Sun、Xerox、Apple、MicroSoft、Novell名公司,共同出资成立
Unicode协会(The Unicode Consortium),并由协会设立非营利的
Unicode公司。Unicode协会成立之后,将原先的工作小组扩编为
Unicode技术委员会(Unicode Technical Committee),专责Unicode
的字符搜集、整理、编码等工作。推动Unicode成为国际标准的工作,
则由Unicode公司负责。Unicode草案第一版于1989年9月发表,历经
多次修订后,分别于1991、92年出版了Unicode标准第一版(The
Unicode Standard, version 1.0)的第一、第二册。
由于Unicode协会持续的游说和施压,WG2终于放弃原先选择的ISO2022
八位延伸编码结构,改采Unicode的编码方式,亦即连续编码不再避开
C0和C1句柄区。1991年10月,历经几个月的协商之后,WG2和Unicode
协会达成协议,将Unicode并入ISO10646成为第0字面。之后各国语言字
元的搜集、整理和编码等工作转由WG2主导,而Unicode协会则积极协助
WG2,但双方仍然各自出版自己的编码标准。由于双方标准的整合是在
Unicode标准第一版第一册出版之后才展开的,因此该版次标准的第二
册特别在第一章里说明了为因应合并工作所做的编码区和字符集修订项
目。ISO于199月出版ISO10646-1(注4)的第一版,而第二版则经过多年
修订之后于今年3月出版。介于ISO10646-1第一、二版之间的Unicode标
准第二版于1996年出版,而对应于ISO10646-1第二版的Unicode标准第三
版于今年一月出版。今年三月,在北京举行的WG2第38次会议正式通过
ISO10646-2(注5)最终草案,预定五月底编辑完成后送交各会员国审
查,如无意外,明后年将会正式出版。
二、编码结构与字符集
ISO10646字符码的正规形式(可简称为UCS-4)为32个位,划分
成4个八位,如【图一】所示。这4个八位,由左而右命名为群
八位(G-octet)、面八位(P-octet)、列八位(R-octet)
和格八位(C-octet),分别代表编码结构中的群组(group)、
字面(plane)、列(row)与格(cell)。ISO10646规定其字符码
的b32必须为0,因而整个编码空间可区分为128个群组(群八位
的值为00~7Fh(注6)),每一群组由256个字面所组成(面八位
元为00~FFh),每一个字面由256列所组成(列八位为00~FFh),
每一列则包含256格(格八位为00~FFh),为一个编码位置。除
此之外,ISO10646还规定每一个字面的最后两个编码位置FFFEh和
FFFFh,保留不用。所以,ISO10646整个编码空间总共256×128=
32,768个字面,每个字面为256×256-2=65,534个编码位置,合
计65534×32768=2,147,418,112个编码位置。
ISO10646的第0群组第0字面(群八位和面八位的值都为00h)
称为「基本多语文字面」(Basic Multi-lingual Plane, BMP),
其编码字符与Unicode相同。BMP之外的32,767个字面区分为辅助字
面(supplementary planes)和专用字面(private use planes)。
辅助字面用以收容WG2陆续收集、整理和编码的各国语文字元;专
用字面的内容WG2不予规定,保留供使用者自行添加ISO10646未收
容的字符。专用字面共8,226个,包括00h群组的0Fh、10h和E0~
FFh共计34个字面,以及60~7Fh共32个群组的8,192个字面。除了
这8,226个专用字面之外,其余的24,541个字面都是辅助字面。
当计算机系统只使用BMP的字符码时,可以省略群八位和面八位
元,因而而将字符码由32个位缩短为16个位,称为ISO10646
字符码的基本面形式(可简称为UCS-2),其实也可视同于Unicode。
ISO10646所有字面中,目前仅有第0、第1和第2字面真正收容
编码字符。ISO10646的BMP和Unicode的编码字符,依其UCS-2编
码序介绍如下:
(1)0000~007Fh:基本拉丁字母区。其中0000~001Fh为C0控
制码,0020h为空格(space),0021~007Eh为ASCII图形
字符,007Fh为句柄DEL。事实上,这128个字符码只要
把前8个位去掉就可变成习见的8位形式的ASCII码。
(2)0080~00A0h:句柄区。其中0080~009Fh为C1句柄,
00A0h为不中断空格(no-break space)。
(3)00A1~1FFFh:拼音文字区。收容除基本拉丁字母以外的各种
拼音文字字符,包括欧洲各国语言、希腊文、斯拉夫语文、
希伯来文、阿拉伯文、亚美尼亚文、印度各地方言、马来文、
泰文、寮文、柬普寨文、满文、蒙文、藏文、印地安语文等。
(4)2000~28FFh:符号区。收容各种符号,包括标点符号、上下
标、钱币符号、数字、箭头、数学符号、工程符号、光学辨
识符号、带圈或带括符的文数字、表格绘制符号、地理图标、
盲用点字、装饰图形等。
(5)2E80~33FFh:中日韩符号区。收容康熙字典部首、中日韩辅
助部首、注音符号、日本假名、韩文音符,中日韩的符号、
标点、带圈或带括符文数字、月份,以及日本的假名组合、
单位、年号、月份、日期、时间等。
(6)3400~4DFFh:中日韩认同表意文字扩充A区,总计收容6,582
个中日韩汉字。
(7)4E00~9FFFh:中日韩认同表意文字区,总计收容20,902个中
日韩汉字。
(8)A000~A4FFh:彝族文字区,收容中国南方彝族文字和字根。
(9)AC00~D7FFh:韩文拼音组合字区,收容以韩文音符拼成的文
字。
(10)D800~DFFFh:S区,专用于UTF-16,详情后叙。
(11)E000~F8FFh:专用字区,其内容WG2不予规定,保留供使用
者自行添加ISO10646未收容的字符。
(12)F900~FAFFh:中日韩兼容表意文字区,总计收容302个中日
韩汉字。何谓兼容表意文字,留待后叙。
(13)FB00~FFFDh:文字表现形式区,收容组合拉丁文字、希伯来
文、阿拉伯文、中日韩直式标点、小符号、半角符号、全角
符号等。
WG2集各国专家之力共同整理全世界古今各种语言文字和符号,陆
续编入ISO10646。WG2依语言特性把各种文字区分为表意文字和非表
意文字两类,表意文字其实就是东亚各国所使用发源于中国的汉字,
主要包括台湾、中国、日本、南北韩、越南、新加坡和港澳地区所使
用的汉字。除汉字之外的所有其它文字,一律归类为非表意文字,绝
大部分为拼音文字。ISO10646的BMP和Unicode同时收编非表意文字、
符号和表意文字。但全世界古今各种语言文字和符号的数量何其庞大,
单靠BMP不足以容纳。WG2截至目前为止所收集、整理的非表意文字和
符号部分,扣除已编入BMP者,其余全部编入第1字面,由于其内容项
目过于庞杂,本文不拟介绍。而表意文字部分扣除已编入BMP者,其
余全部编入第二字面,其内容为:
(1)中日韩认同表意文字扩充B区:总计42,807个中日韩越汉字,
编码范围为0002-0100~0002-A836h。
(2)CNS11643兼容字符区:收容被认同的CNS11643字符527个,编
码范围为0002-F800~0002-FA16h。
WG2制订ISO10646编码字符集,首先由各会员体或观察员收集整理
自己国家的文字和符号向WG2提案(注7),WG2每半年召开会议审查
字符集提案,通过者即予以编码或是等候汇集更多字符集后再进行
编码。非表意文字或符号,因为字集小或是只有某个国家使用,通
常直接在WG2会议上讨论即可。但汉字字集规模庞大且为多个国家和
地区共同使用,WG2为此设置表意文字书记小组(Ideograph Rapporteur
Group, IRG)专责收集各国汉字字集,加以比对认同汇整成为整体
性字集之后再向WG2提出。IRG所建议的字符集,WG2向来都是直接
接受予以编码。IRG各会员体所提出的汉字都源自中国,难免有些字
的字形相同或极为近似。为了避免ISO10646编码表出现重复字造成
使用者困扰,IRG制订了表意文字认同规则。凡是依规则应予认同的
汉字,一律合并成一字赋予一个编码。不过为了尊重各国对各自文
字的主控权,WG2特别在ISO10646编码表中并列同一汉字不同来源的
各自字形。
认同规则不仅运用于整合不同来源的汉字,同时适用于相同来源
的汉字。例如,在我国中文码国家标准CNS11643的字集里就收编了
两个极为相似的「图」字,分别赋予两个不同的码1-6837h和6-5B5Bh,
这两个「图」字,依认同规则必须合并为一个,于是后者被前者认
同掉了。详言之,CNS的1-6837h和6-5B5Bh都对应到Unicode的5716h
(或ISO10646的0000-5716h),但是Unicode的5716h却只对应到CNS
的1-6837h。当我们把数据从CNS码转换成Unicode,再由Unicode转回
CNS码时,将发生6-5B5Bh→5716h→1-6837h的结果,这种现象称为去
回转码(round-trip conversion)错误。解决之道无他,必须在
Unicode或ISO10646字集中多加上被认同掉的字符并另外赋予编码
(称为兼容字符),做到CNS字集与ISO10646字集一对一(但不必
也无法做到映成)。ISO10646第2字面所收容的CNS兼容字集,就是
我国为了达到正确去回转码的目的,经多年力争所得成果。换言之,
CNS11643现有中文字集已全数编入ISO10646编码表中。
三、UTF-16与UTF-8
ISO10646的编码空间足以容纳古今人类使用过的所有文字和符号,
但目前真正被使用的文字或符号,绝大多数都已编入BMP,它们的使
用频率可能超过99%,甚至99.99%。换言之,就99%以上的使用者或
使用场合而言,16位的Unicode已是足敷需求,32位的ISO10646
正规编码则显得割鸡用牛刀。32位编码不只要比16位编码占用
多一倍的记忆或储存空间,而且在网络传输和信息处理上也需花费
比较长的时间。就经济效益而言,将来计算机和网络选择使用Unicode
的可能性,很明显地要高于选择使用32位的ISO10646正规编码。
问题是,在Unicode的世界里,遇到必须使用646第1、第2字面甚至
更后方字面的字符时,怎么办?Unicode协会提出的解决方式称为
UTF-16或代理法(surrogates)。 UTF为"a UCS(or Unicode)
Transformation Format"的缩写,UTF-16意即把原为32位的
ISO10646字符码转换为2或多个16位的Unicode。目前的作法是组
合两个Unicode字符码来代表一个ISO10646字符,如【图二】所示,
所以又称为代表法。两个做为代表的Unicode,位于前方(左方)
者称为高半字符,限定只能选用D800~DBFFh当中之一,位于后方
(右方)者称为低半字符,限制只可从DC00~DFFFh当中选择。高
低半字符的编码位置各为1,024=4×256,因此UTF-16总计可提供
(4×256)×(4×256)=16×65536个编码位置,亦即16个字面。
对BMP而言,当然无需使用UTF-16转码,所以UTF-16主要应用于
ISO10646的第1~第14字面(因为第15字面为专用字面,WG2不予编
码)。将ISO10646字符(编码范围0001-0000~000E-FFFFh)以
UFT-16转换成Unicode组合形式的规则,如【图三】所示,图中为了
方便对应16进制,特别将字符码表现成每4个位一组,中间以短杠
分隔。转换方式不难,将原来的32位ISO10646字符码,从右往左
取出10个位(即图中的Y10~Y1)前头附加上特定的6个位110111,
即成为低半字符。接着往左取出6个位(即图中的Y16~Y11)做为
高半字符的最低6个位,然后再往左取出4个位(即图中的Z4~Z1,
相当于Y20~Y17,其值可显示第0~第15字面),将其值减1,置于刚
才那6个位的左方,最后在最前方附加上特定的6个位110110,即
成为高半字符。以上所介绍的是UTF-16转换的观念,至于UTF-16的转
换公式和还原公式,请详见ISO10646标准或Unicode标准。
请特别注意,UTF-16系针对Unicode世界所设计的。也就是说,当
因特网和大部分的计算机都已经采用Unicode了,UTF-16才可用来表
现ISO10646第1~第14字面的字符码。很不幸的事实并非如此,现在
是ASCII世界而非Unicode世界。当某一个Unicode离开温室(某个以
Unicode为内码的操作系统或应用程序)之后,马上会被网络设备切
成两个8位的字节,并严密检查是否有任何字节为C0句柄,
至少数千个Unicoe将因此变得残缺不全。为了能让Unicode和ISO10646
字符码能安然通行于ASCII世界,Unicode协会特别提出UTF-8以解决
问题。UTF-8意即把原为32位的ISO10元码或原为16位的Unicode
转换为多个8位的字节。
利用UTF-8转码规则可将一个Unicode或ISO10646字符码转换成1~4
个字节的编码,如【图四】所示。UTF-8的转换规则很简单:若原始
字符码位于0000~007Fh(或0000-0000~0000-007Fh)的范围内,则
直接截取最右8个位即可,转换结果其实就是ASCII码。若原始字符
码大于007Fh(或0000-007Fh),亦即超出ASCII范围时,就必须转换
成2~4个字节。UTF-8规定,以转换后第1字节起头连续设为"1"
的标记位的数目表示转换成几个字节:110表示转换结果为2个位
元组,1110表示3个字节,而11110则表示4个字节。至于跟随在标
记位之后设为0的位,其在分隔标记位和字符码位。第2~第4
字节起头两个位被设为10当做识别,剩下的6个位才做为字符码
位使用。总计,2字节UTF-8码剩下11个字符码位,可用以转换
0080~07FFh的原始字符码。3字节剩下16个字符码位,可用以转换
0800~FFFFh的原始字符码。而4字节则剩下21个字符码位,可用来
转换0001-0000~001F-FFFh(即ISO10646第1~第31字面)的原始字
元码。请注意,虽然4个字节的UTF-8编码可包容1~3个字节的码,
3个字节的编码可包容1~2个字节的码,以及2个字节的编码可包
容1个字节的码,但是UTF-8规定转码时必须选择最短者。换言之,
ASCCI区只能转换成单一位,0080~07FFh的原始字符码只能转换成2
个位组长度,依此类推。
参考数据:
注1:ISO为国际标准组织(International Organization for
Standardization)的英文缩写;IEC为联合国下属国际电
气技术委员会(International Electro-technical
Commission)的英文缩写;JTC1系由ISO和IEC双方协议共
组的第一联合技术委员会(Join Technical Committee One),
负责制订与信息处理、信息技术相关的国际标准;JTC1/SC2
为设于JTC1之下的第二分组委员会(Sub-Committee Two);
而JTC1/SC2/WG2则是JTC1/SC2之下的第二工作组(Working
Group Two)。在我国,经济部标准检验局设有对应ISO/IEC
JTC1/SC2的组织,称为信息及通信国家标准起草委员会,
而对应ISO/IEC JTC1/SC2/WG2者,称为中文信息标准分组
委员会。笔者同时担任这两个组织的委员。
注2:C0句柄区指的是编码为0~31的32个句柄(其bit-8为0),
而C1句柄区则是意指128~159的32个句柄(其bit-8为1)。
关于C0和C1句柄详情,请参考ISO6429或CNS13479。
注3:国内有人将Unicode译为「统一码」。
注4:ISO10646-1为该标准的第一部份,正式名称为"ISO/IEC 10646-1:
Universal Multiple-Octet Coded Character Set - UCS - Part 1:
Architecture and Basic Multilingual Plane (BMP)",其
内容仅及于ISO10646的编码结构和第0字面的编码表。
注5:ISO10646-2为该标准的第二部份,正式名称为"ISO/IEC 10646-2:
Universal Multiple-Octet Coded Character Set - UCS - Part 2:
CJK Unified Ideographs Supplementary Plane, General Scriptsand
Symbols Plane, General Purpose Plane",其内容主要包括
第1字面非表意文字、符号的编码表,以及第2字面中日韩认同
表意文字和兼容表意文字的编码表。
注6:在此,h表示16进制数字,每一数字的值为0~15,分别表示
为0~9和 A(10)、B(11)、C(12)、E(13)、D(14)和F(15)。
注7:我国为WG2的观察员和IRG的会员体,本文作者目前为这两个
组织的我国代表。
一、缘起
1960年代初期,美国国会图书馆(Library of Congress, LC)的
Henriette Avram等人开始研拟机读编目格式,同时James Agenboard
等人也制订了英文的字符集和交换码,以做为美国图书馆界书目交
换的共同标准。LC交换码随后发展成为美国的国家标准ASCII(American
Standard Codefor Information Interchange),而且还进一步演
变成世界性的计算机字符编码标准ISO646(其全名为7-bit coded
character set for information interchange)。时至今日,虽然
一个字节(byte)的长度已经从7个位(bit)增加为8个位,
ASCII和ISO646 仍然是计算机与网络世界里要的奠基标准。
依ASCII和ISO646的规定,7个位所能提供的128个编码位置(编
码范围为0~127)被区分为两部分:94个图形字符码和34个控制字
元码。图形字符包括52个大小写英文字母﹑10个阿拉伯数字﹑9个标
点符号﹑6个括号,以及17个其它符号,编码范围从33到126。控制
字符则包括10个传输控制字符、6个版面调整字符、4个设备控制字
元、 4个信息分隔字符和10个特殊控制字符,其编码为0~32和127。
当计算机或网络设备收到一连串的位信号时,通常会一边接收一边
切分为字节(即每8个位一切),并且立刻分辨刚收到的位
组究竟是控制字符码还是图形字符码。若是属收讯设备相关的控制
字符时(例如传输控制、编码为7的BELL等字符),当计算机或网络
设备会截留该字符并立即做出对应动作(例如BELL字符会驱使收讯
设备叫一声),否则不予处理而传送给后续设备。换言之,计算机和
网络设备会吃掉位串里的特定控制字符码。
随着计算机功能的日趋强大与价格的日趋便宜,其应用领域也越来
越广。但是随之而来的各种编码需求,却使得单一字节的编码方
式,因编码空间太小,变得不足以因应各种应用程序的需求。中文
字、排版系统的标志符号、非英语拼音字母和图形符号等的编码,
需要使用2或多个字节来编码。同时,为了预防这些多字节字符
码被计算机或网络设备「吃掉」其中的某个字节,编码时必须避开
每个字节的0~32和127这34个句柄。这种做法严重浪费编码空
间,就多字节扩充编码的国际标准ISO2022而言,两个8位的位
元组只能提供最多188个控制字符和35,344个文字形符号的编码空间,
共计35,532个编码位置,但是16个位的编码空间事实上高达65,536。
两者相比较,ISO2022的16位编码只能达到最大编码空间的54%,
显得利用率很差。同时在应用层次的编码,由于厂商众多又缺乏共
识,往往你编你的码、我编我的码,其后果则是引发万码奔腾的乱
象。
为容纳全世界各种语言的字符和符号,ISO的一些会员国于1984年
发起制定新的国际字符集编码标准。新标准由工作小组ISO/IEC
JTC1/SC2/WG2(注1)负责拟订(以下简称WG2),最后定案的标准
命名为"Universal Multiple-Octet Coded Character Set"
(简称UCS),其编号则订为ISO/IEC 10646。依WG2原来的规划,
ISO10646的编码结构系沿袭ISO2022八位延伸编码结构以避开C0和
C1两个句柄区(注2),但打破每个字符码里的所有字节的bit-8
(即最左边的位,其值为28=128)必须都设为0或是都设为1的限制,
以提高编码空间的使用率。同时,为了能有足够位置以容纳全世界各
种语言的字符和符号,以及为了配合微处理器以8、16、32甚或64个
位为一个运算处理单位的趋势,ISO10646的字符码长度被规定为
定长的4个八位(octet)。
ISO10646草案初稿一经公布,其编码结构立即遭到美国部份计算机
业者的反对。1988年初,美国Xerox公司的Joe Becker倡议以新的编
码结构,另外编订世界性字符编码标准:将计算机字符集编码的基本
单位由现行的7或8个位一举扩充为16个位,并且充分利用65,536
个编码位置以容纳全世界各种语言的字符和常用符号。新的字符集
编码标准被命名为"Unicode"(注3)。一群来自Xerox公司和Apple
公司的工程师组成工作小组,负责Unicode的原始设计工作。1991年
元月,十多家计算机硬软件、网络和信息服务业者,包括:IBM、DEC、
Sun、Xerox、Apple、MicroSoft、Novell名公司,共同出资成立
Unicode协会(The Unicode Consortium),并由协会设立非营利的
Unicode公司。Unicode协会成立之后,将原先的工作小组扩编为
Unicode技术委员会(Unicode Technical Committee),专责Unicode
的字符搜集、整理、编码等工作。推动Unicode成为国际标准的工作,
则由Unicode公司负责。Unicode草案第一版于1989年9月发表,历经
多次修订后,分别于1991、92年出版了Unicode标准第一版(The
Unicode Standard, version 1.0)的第一、第二册。
由于Unicode协会持续的游说和施压,WG2终于放弃原先选择的ISO2022
八位延伸编码结构,改采Unicode的编码方式,亦即连续编码不再避开
C0和C1句柄区。1991年10月,历经几个月的协商之后,WG2和Unicode
协会达成协议,将Unicode并入ISO10646成为第0字面。之后各国语言字
元的搜集、整理和编码等工作转由WG2主导,而Unicode协会则积极协助
WG2,但双方仍然各自出版自己的编码标准。由于双方标准的整合是在
Unicode标准第一版第一册出版之后才展开的,因此该版次标准的第二
册特别在第一章里说明了为因应合并工作所做的编码区和字符集修订项
目。ISO于199月出版ISO10646-1(注4)的第一版,而第二版则经过多年
修订之后于今年3月出版。介于ISO10646-1第一、二版之间的Unicode标
准第二版于1996年出版,而对应于ISO10646-1第二版的Unicode标准第三
版于今年一月出版。今年三月,在北京举行的WG2第38次会议正式通过
ISO10646-2(注5)最终草案,预定五月底编辑完成后送交各会员国审
查,如无意外,明后年将会正式出版。
二、编码结构与字符集
ISO10646字符码的正规形式(可简称为UCS-4)为32个位,划分
成4个八位,如【图一】所示。这4个八位,由左而右命名为群
八位(G-octet)、面八位(P-octet)、列八位(R-octet)
和格八位(C-octet),分别代表编码结构中的群组(group)、
字面(plane)、列(row)与格(cell)。ISO10646规定其字符码
的b32必须为0,因而整个编码空间可区分为128个群组(群八位
的值为00~7Fh(注6)),每一群组由256个字面所组成(面八位
元为00~FFh),每一个字面由256列所组成(列八位为00~FFh),
每一列则包含256格(格八位为00~FFh),为一个编码位置。除
此之外,ISO10646还规定每一个字面的最后两个编码位置FFFEh和
FFFFh,保留不用。所以,ISO10646整个编码空间总共256×128=
32,768个字面,每个字面为256×256-2=65,534个编码位置,合
计65534×32768=2,147,418,112个编码位置。
ISO10646的第0群组第0字面(群八位和面八位的值都为00h)
称为「基本多语文字面」(Basic Multi-lingual Plane, BMP),
其编码字符与Unicode相同。BMP之外的32,767个字面区分为辅助字
面(supplementary planes)和专用字面(private use planes)。
辅助字面用以收容WG2陆续收集、整理和编码的各国语文字元;专
用字面的内容WG2不予规定,保留供使用者自行添加ISO10646未收
容的字符。专用字面共8,226个,包括00h群组的0Fh、10h和E0~
FFh共计34个字面,以及60~7Fh共32个群组的8,192个字面。除了
这8,226个专用字面之外,其余的24,541个字面都是辅助字面。
当计算机系统只使用BMP的字符码时,可以省略群八位和面八位
元,因而而将字符码由32个位缩短为16个位,称为ISO10646
字符码的基本面形式(可简称为UCS-2),其实也可视同于Unicode。
ISO10646所有字面中,目前仅有第0、第1和第2字面真正收容
编码字符。ISO10646的BMP和Unicode的编码字符,依其UCS-2编
码序介绍如下:
(1)0000~007Fh:基本拉丁字母区。其中0000~001Fh为C0控
制码,0020h为空格(space),0021~007Eh为ASCII图形
字符,007Fh为句柄DEL。事实上,这128个字符码只要
把前8个位去掉就可变成习见的8位形式的ASCII码。
(2)0080~00A0h:句柄区。其中0080~009Fh为C1句柄,
00A0h为不中断空格(no-break space)。
(3)00A1~1FFFh:拼音文字区。收容除基本拉丁字母以外的各种
拼音文字字符,包括欧洲各国语言、希腊文、斯拉夫语文、
希伯来文、阿拉伯文、亚美尼亚文、印度各地方言、马来文、
泰文、寮文、柬普寨文、满文、蒙文、藏文、印地安语文等。
(4)2000~28FFh:符号区。收容各种符号,包括标点符号、上下
标、钱币符号、数字、箭头、数学符号、工程符号、光学辨
识符号、带圈或带括符的文数字、表格绘制符号、地理图标、
盲用点字、装饰图形等。
(5)2E80~33FFh:中日韩符号区。收容康熙字典部首、中日韩辅
助部首、注音符号、日本假名、韩文音符,中日韩的符号、
标点、带圈或带括符文数字、月份,以及日本的假名组合、
单位、年号、月份、日期、时间等。
(6)3400~4DFFh:中日韩认同表意文字扩充A区,总计收容6,582
个中日韩汉字。
(7)4E00~9FFFh:中日韩认同表意文字区,总计收容20,902个中
日韩汉字。
(8)A000~A4FFh:彝族文字区,收容中国南方彝族文字和字根。
(9)AC00~D7FFh:韩文拼音组合字区,收容以韩文音符拼成的文
字。
(10)D800~DFFFh:S区,专用于UTF-16,详情后叙。
(11)E000~F8FFh:专用字区,其内容WG2不予规定,保留供使用
者自行添加ISO10646未收容的字符。
(12)F900~FAFFh:中日韩兼容表意文字区,总计收容302个中日
韩汉字。何谓兼容表意文字,留待后叙。
(13)FB00~FFFDh:文字表现形式区,收容组合拉丁文字、希伯来
文、阿拉伯文、中日韩直式标点、小符号、半角符号、全角
符号等。
WG2集各国专家之力共同整理全世界古今各种语言文字和符号,陆
续编入ISO10646。WG2依语言特性把各种文字区分为表意文字和非表
意文字两类,表意文字其实就是东亚各国所使用发源于中国的汉字,
主要包括台湾、中国、日本、南北韩、越南、新加坡和港澳地区所使
用的汉字。除汉字之外的所有其它文字,一律归类为非表意文字,绝
大部分为拼音文字。ISO10646的BMP和Unicode同时收编非表意文字、
符号和表意文字。但全世界古今各种语言文字和符号的数量何其庞大,
单靠BMP不足以容纳。WG2截至目前为止所收集、整理的非表意文字和
符号部分,扣除已编入BMP者,其余全部编入第1字面,由于其内容项
目过于庞杂,本文不拟介绍。而表意文字部分扣除已编入BMP者,其
余全部编入第二字面,其内容为:
(1)中日韩认同表意文字扩充B区:总计42,807个中日韩越汉字,
编码范围为0002-0100~0002-A836h。
(2)CNS11643兼容字符区:收容被认同的CNS11643字符527个,编
码范围为0002-F800~0002-FA16h。
WG2制订ISO10646编码字符集,首先由各会员体或观察员收集整理
自己国家的文字和符号向WG2提案(注7),WG2每半年召开会议审查
字符集提案,通过者即予以编码或是等候汇集更多字符集后再进行
编码。非表意文字或符号,因为字集小或是只有某个国家使用,通
常直接在WG2会议上讨论即可。但汉字字集规模庞大且为多个国家和
地区共同使用,WG2为此设置表意文字书记小组(Ideograph Rapporteur
Group, IRG)专责收集各国汉字字集,加以比对认同汇整成为整体
性字集之后再向WG2提出。IRG所建议的字符集,WG2向来都是直接
接受予以编码。IRG各会员体所提出的汉字都源自中国,难免有些字
的字形相同或极为近似。为了避免ISO10646编码表出现重复字造成
使用者困扰,IRG制订了表意文字认同规则。凡是依规则应予认同的
汉字,一律合并成一字赋予一个编码。不过为了尊重各国对各自文
字的主控权,WG2特别在ISO10646编码表中并列同一汉字不同来源的
各自字形。
认同规则不仅运用于整合不同来源的汉字,同时适用于相同来源
的汉字。例如,在我国中文码国家标准CNS11643的字集里就收编了
两个极为相似的「图」字,分别赋予两个不同的码1-6837h和6-5B5Bh,
这两个「图」字,依认同规则必须合并为一个,于是后者被前者认
同掉了。详言之,CNS的1-6837h和6-5B5Bh都对应到Unicode的5716h
(或ISO10646的0000-5716h),但是Unicode的5716h却只对应到CNS
的1-6837h。当我们把数据从CNS码转换成Unicode,再由Unicode转回
CNS码时,将发生6-5B5Bh→5716h→1-6837h的结果,这种现象称为去
回转码(round-trip conversion)错误。解决之道无他,必须在
Unicode或ISO10646字集中多加上被认同掉的字符并另外赋予编码
(称为兼容字符),做到CNS字集与ISO10646字集一对一(但不必
也无法做到映成)。ISO10646第2字面所收容的CNS兼容字集,就是
我国为了达到正确去回转码的目的,经多年力争所得成果。换言之,
CNS11643现有中文字集已全数编入ISO10646编码表中。
三、UTF-16与UTF-8
ISO10646的编码空间足以容纳古今人类使用过的所有文字和符号,
但目前真正被使用的文字或符号,绝大多数都已编入BMP,它们的使
用频率可能超过99%,甚至99.99%。换言之,就99%以上的使用者或
使用场合而言,16位的Unicode已是足敷需求,32位的ISO10646
正规编码则显得割鸡用牛刀。32位编码不只要比16位编码占用
多一倍的记忆或储存空间,而且在网络传输和信息处理上也需花费
比较长的时间。就经济效益而言,将来计算机和网络选择使用Unicode
的可能性,很明显地要高于选择使用32位的ISO10646正规编码。
问题是,在Unicode的世界里,遇到必须使用646第1、第2字面甚至
更后方字面的字符时,怎么办?Unicode协会提出的解决方式称为
UTF-16或代理法(surrogates)。 UTF为"a UCS(or Unicode)
Transformation Format"的缩写,UTF-16意即把原为32位的
ISO10646字符码转换为2或多个16位的Unicode。目前的作法是组
合两个Unicode字符码来代表一个ISO10646字符,如【图二】所示,
所以又称为代表法。两个做为代表的Unicode,位于前方(左方)
者称为高半字符,限定只能选用D800~DBFFh当中之一,位于后方
(右方)者称为低半字符,限制只可从DC00~DFFFh当中选择。高
低半字符的编码位置各为1,024=4×256,因此UTF-16总计可提供
(4×256)×(4×256)=16×65536个编码位置,亦即16个字面。
对BMP而言,当然无需使用UTF-16转码,所以UTF-16主要应用于
ISO10646的第1~第14字面(因为第15字面为专用字面,WG2不予编
码)。将ISO10646字符(编码范围0001-0000~000E-FFFFh)以
UFT-16转换成Unicode组合形式的规则,如【图三】所示,图中为了
方便对应16进制,特别将字符码表现成每4个位一组,中间以短杠
分隔。转换方式不难,将原来的32位ISO10646字符码,从右往左
取出10个位(即图中的Y10~Y1)前头附加上特定的6个位110111,
即成为低半字符。接着往左取出6个位(即图中的Y16~Y11)做为
高半字符的最低6个位,然后再往左取出4个位(即图中的Z4~Z1,
相当于Y20~Y17,其值可显示第0~第15字面),将其值减1,置于刚
才那6个位的左方,最后在最前方附加上特定的6个位110110,即
成为高半字符。以上所介绍的是UTF-16转换的观念,至于UTF-16的转
换公式和还原公式,请详见ISO10646标准或Unicode标准。
请特别注意,UTF-16系针对Unicode世界所设计的。也就是说,当
因特网和大部分的计算机都已经采用Unicode了,UTF-16才可用来表
现ISO10646第1~第14字面的字符码。很不幸的事实并非如此,现在
是ASCII世界而非Unicode世界。当某一个Unicode离开温室(某个以
Unicode为内码的操作系统或应用程序)之后,马上会被网络设备切
成两个8位的字节,并严密检查是否有任何字节为C0句柄,
至少数千个Unicoe将因此变得残缺不全。为了能让Unicode和ISO10646
字符码能安然通行于ASCII世界,Unicode协会特别提出UTF-8以解决
问题。UTF-8意即把原为32位的ISO10元码或原为16位的Unicode
转换为多个8位的字节。
利用UTF-8转码规则可将一个Unicode或ISO10646字符码转换成1~4
个字节的编码,如【图四】所示。UTF-8的转换规则很简单:若原始
字符码位于0000~007Fh(或0000-0000~0000-007Fh)的范围内,则
直接截取最右8个位即可,转换结果其实就是ASCII码。若原始字符
码大于007Fh(或0000-007Fh),亦即超出ASCII范围时,就必须转换
成2~4个字节。UTF-8规定,以转换后第1字节起头连续设为"1"
的标记位的数目表示转换成几个字节:110表示转换结果为2个位
元组,1110表示3个字节,而11110则表示4个字节。至于跟随在标
记位之后设为0的位,其在分隔标记位和字符码位。第2~第4
字节起头两个位被设为10当做识别,剩下的6个位才做为字符码
位使用。总计,2字节UTF-8码剩下11个字符码位,可用以转换
0080~07FFh的原始字符码。3字节剩下16个字符码位,可用以转换
0800~FFFFh的原始字符码。而4字节则剩下21个字符码位,可用来
转换0001-0000~001F-FFFh(即ISO10646第1~第31字面)的原始字
元码。请注意,虽然4个字节的UTF-8编码可包容1~3个字节的码,
3个字节的编码可包容1~2个字节的码,以及2个字节的编码可包
容1个字节的码,但是UTF-8规定转码时必须选择最短者。换言之,
ASCCI区只能转换成单一位,0080~07FFh的原始字符码只能转换成2
个位组长度,依此类推。
参考数据:
注1:ISO为国际标准组织(International Organization for
Standardization)的英文缩写;IEC为联合国下属国际电
气技术委员会(International Electro-technical
Commission)的英文缩写;JTC1系由ISO和IEC双方协议共
组的第一联合技术委员会(Join Technical Committee One),
负责制订与信息处理、信息技术相关的国际标准;JTC1/SC2
为设于JTC1之下的第二分组委员会(Sub-Committee Two);
而JTC1/SC2/WG2则是JTC1/SC2之下的第二工作组(Working
Group Two)。在我国,经济部标准检验局设有对应ISO/IEC
JTC1/SC2的组织,称为信息及通信国家标准起草委员会,
而对应ISO/IEC JTC1/SC2/WG2者,称为中文信息标准分组
委员会。笔者同时担任这两个组织的委员。
注2:C0句柄区指的是编码为0~31的32个句柄(其bit-8为0),
而C1句柄区则是意指128~159的32个句柄(其bit-8为1)。
关于C0和C1句柄详情,请参考ISO6429或CNS13479。
注3:国内有人将Unicode译为「统一码」。
注4:ISO10646-1为该标准的第一部份,正式名称为"ISO/IEC 10646-1:
Universal Multiple-Octet Coded Character Set - UCS - Part 1:
Architecture and Basic Multilingual Plane (BMP)",其
内容仅及于ISO10646的编码结构和第0字面的编码表。
注5:ISO10646-2为该标准的第二部份,正式名称为"ISO/IEC 10646-2:
Universal Multiple-Octet Coded Character Set - UCS - Part 2:
CJK Unified Ideographs Supplementary Plane, General Scriptsand
Symbols Plane, General Purpose Plane",其内容主要包括
第1字面非表意文字、符号的编码表,以及第2字面中日韩认同
表意文字和兼容表意文字的编码表。
注6:在此,h表示16进制数字,每一数字的值为0~15,分别表示
为0~9和 A(10)、B(11)、C(12)、E(13)、D(14)和F(15)。
注7:我国为WG2的观察员和IRG的会员体,本文作者目前为这两个
组织的我国代表。