unicode.org制定的编码机制,要将全世界常用文字都函括进去。
在1.0中是16位编码,由U+0000到U+FFFF。每个2byte码对应一个字符;在2.0开始抛弃了16位限制,原来的16位作为基本位平面,另外增加了16个位平面,相当于20位编码,编码范围0到0×10FFFF。
ISO制定的ISO 10646标准所定义的Universal Character Set,采用4byte编码。
ISO与unicode.org是两个不同的组织,因此最初制定了不同的标准;但自从unicode2.0开始,unicode采用了与ISO 10646-1相同的字库和字码,ISO也承诺ISO 10646将不会给超出0×10FFFF的UCS-4编码赋值,使得两者保持一致。

0到0×10FFFF之间,基本上就是unicode编码的实现。它是变长码,与CPU字序有关,但因为最省空间,常作为网络传输的外码。UTF-16是unicode的preferred encoding。0到0×10FFFF)的32位编码,相当于UCS-4的子集。Unicode是一个字符集,可以看作为内码。
而UTF是一种编码方式,它的出现是因为unicode不适宜在某些场合直接传输和处理。UTF-16直接就是unicode编码,没有变换,但它包含了0×00在编码内,头256字节码的第一个byte都是0×00,在操作系统(C语言)中有特殊意义,会引起问题。采用UTF-8编码对unicode的直接编码作些变换可以避免这问题,并带来一些优点。
国际标准ISO 10646定义了通用字符集 (Universal Character Set,UCS)。UCS是所有其他字符集标准的一个超集,它保证与其他字符集是双向兼容的。就是说,如果你将任何文本字符串翻译到UCS格式,然后再翻译回原编码,你不会丢失任何信息。
UCS包含了用于表达所有已知语言的字符。不仅包括拉丁语、希腊语、斯拉夫语、希伯来语、阿拉伯语、亚美尼亚语和乔治亚语的描述,还包括中文、日文和韩文这样的象形文字,以及平假名、片假名、孟加拉语、旁遮普语果鲁穆奇字符(Gurmukhi)、泰米尔语、印·埃纳德语(Kannada)、Malayalam、泰国语、老挝语、汉语拼音(Bopomofo)、Hangul、Devangari、Gujarati、Oriya、Telugu以及其他数也数不清的语。对于还没有加入的语言,由于正在研究怎样在计算机中最好地编码它们,因而最终它们都将被加入。这些语言包括Tibetian、高棉语、Runic(古代北欧文字)、埃塞俄比亚语、其他象形文字,以及各种各样的印-欧语系的语言,还包括挑选出来的艺术语言比如Tengwar、Cirth和克林贡语(Klingon)。UCS还包括大量的图形的、印刷用的、数学用的和科学用的符号,包括所有由TeX、Postscript、MS-DOS、MS-Windows、Macintosh、OCR 字体,以及许多其他字处理和出版系统提供的字符。
ISO 10646定义了一个31位的字符集。然而,在这巨大的编码空间中,迄今为止只分配了前65534个码位(0×0000到0xFFFD)。这个UCS的 6位子集称为基本多语言面 (Basic Multilingual Plane,BMP)。将被编码在16位BMP以外的字符都属于非常特殊的字符(比如象形文字),且只有专家在历史和科学领域里才会用到它们。按当前的计划,将来也许再也不会有字符被分配到从0×000000到0×10FFFF这个覆盖了超过100万个潜在的未来字符的21位的编码空间以外去了。ISO 10646-1标准第一次发表于1993年,定义了字符集与BMP中内容的架构。定义BMP以外的字符编码的第二部分ISO 10646-2正在准备中,但也许要过好几年才能完成。新的字符仍源源不断地加入到BMP中,但已经存在的字符是稳定的且不会再改变了。
UCS不仅给每个字符分配一个代码,而且赋予了一个正式的名字。表示一个UCS或Unicode值的十六进制数,通常在前面加上“U+”,就象U+0041代表字符”拉丁大写字母A”。UCS字符U+0000到U+007F与US-ASCII(ISO 646)是一致的,U+0000到U+00FF与ISO 8859-1(Latin-1)也是一致的。从U+E000到U+F8FF,已经BM 以外的大范围的编码是为私用保留的。

UCS里有些编码点分配给了组合字符。它们类似于打字机上的无间隔重音键。单个的组合字符不是一个完整的字符。它是一个类似于重音符或其他指示标记,加在前一个字符后面。因而,重音符可以加在任何字符后面。那些最重要的被加重的字符,就象普通语言的正字法(orthographies of common languages)里用到的那种,在UCS里都有自己的位置,以确保同老的字符集的向后兼容性。既有自己的编码位置,又可以表示为一个普通字符跟随一个组合字符的被加重字符,被称为预作字符(precomposed characters)。UCS里的预作字符是为了同没有预作字符的旧编码,比如 ISO 8859,保持向后兼容性而设的。组合字符机制允许在任何字符后加上重音符或其他指示标记,这在科学符号中特别有用,比如数学方程式和国际音标字母,可能会需要在一个基本字符后组合上一个或多个指示标记。
组合字符跟随着被修饰的字符。比如,德语中的元音变音字符 (“拉丁大写字母A 加上分音符”),既可以表示为UCS码U+00C4的预作字符,也可以表示成一个普通 “拉丁大写字母A” 跟着一个”组合分音符”:U+0041 U+0308这样的组合。当需要堆叠多个重音符,或在一个基本字符的上面和下面都要加上组合标记时,可以使用多个组合字符。比如在泰国文中,一个基本字符最多可加上两个组合字符。
不是所有的系统都需要支持象组合字符这样的UCS里所有的先进机制。因此ISO 10646指定了下列三种实现级别:
历史上,有两个独立的,创立单一字符集的尝试。一个是 国际标准化组织(ISO)的ISO 10646项目,另一个是由(一开始大多是美国的)多语言软件制造商组成的协会组织的 Unicode 项目。幸运的是,1991年前后,两个项目的参与者都认识到,世界不需要两个不同的单一字符集。它们合并双方的工作成果,并为创立一个单一编码表而协同工作。两个项目仍都存在并独立地公布各自的标准,但Unicode协会和ISO/IEC JTC1/SC2都同意保持Unicode和ISO 10646标准的码表兼容,并紧密地共同调整任何未来的扩展。
Unicode协会公布的Unicode 标准严密地包含了ISO 10646-1实现级别3的基本多语言面。在两个标准里所有的字符都在相同的位置并且有相同的名字。
Unicode标准额外定义了许多与字符有关的语义符号学,一般而言是对于实现高质量的印刷出版系统的更好的参考。Unicode详细说明了绘制某些语言(比如阿拉伯语)表达形式的算法,处理双向文字(比如拉丁与希伯来文混合文字)的算法和排序与字符串比较 所需的算法,以及其他许多东西。
另一方面,ISO 10646标准,就象广为人知的ISO 8859标准一样,只不过是一个简单的字符集表。它指定了一些与标准有关的术语,定义了一些编码的别名,并包括了规范说明,指定了怎样使用UCS连接其他ISO标准的实现,比如ISO 6429和ISO 2022。还有一些与ISO紧密相关的,比如ISO 14651是关于UCS字符串排序的。
考虑到Unicode标准有一个易记的名字,且在任何好的书店里的Addison-Wesley里有,只花费ISO版本的一小部分,且包括更多的辅助信息,因而它成为使用广泛得多的参考也就不足为奇了。然而,一般认为,用于打印ISO 10646-1标准的字体在某些方面的质量要高于用于打印Unicode 2.0的。专业字体设计者总是被建议说要两个标准都实现,但一些提供的样例字形有显著的区别。ISO 10646-1标准同样使用四种不同的风格变体来显示表意文字如中文、日文和韩文(CJK),而Unicode 2.0的表里只有中文的变体。这导致了普遍的认为Unicode对日本用户来说是不可接收的传说,尽管是错误的。

首先UCS和Unicode只是分配整数给字符的编码表。现在存在好几种将一串字符表示为一串字节的方法。最显而易见的两种方法是将Unicode文本存储为2个或4个字节序列的串。这两种方法的正式名称分别为UCS-2和UCS-4。除非另外指定,否则大多数的字节都是这样的(Bigendian convention)。将一个ASCII或Latin-1的文件转换成UCS-2只需简单地在每个ASCII字节前插入0×00。如果要转换成UCS-4,则必须在每个ASCII字节前插入三个0×00。
在Unix下使用UCS-2(或UCS-4)会导致非常严重的问题。用这些编码的字符串会包含一些特殊的字符,比如‘\0′或‘/’,它们在 文件名和其他C库函数参数里都有特别的含义。另外,大多数使用ASCII文件的UNIX下的工具,如果不进行重大修改是无法读取16位的字符的。基于这些原因,在文件名、文本文件、环境变量等地方,UCS-2不适合作为Unicode的外部编码。
在 ISO 10646-1 Annex R和 RFC 2279里定义的UTF-8编码没有这些问题。它是在Unix风格的操作系统下使用Unicode的明显的方法。
U+0000到U+007F(ASCII)被编码为字节0×00到0×7F(ASCII 兼容)。这意味着只包含7位ASCII字符的文件在ASCII和UTF-8两种编码方式下是一样的。U+007F的UCS字符被编码为一个多个字节的串,每个字节都有标记位集。因此,ASCII字节(0×00-0×7F)不可能作为任何其他字符的一部分。0xC0到0xFD的范围里,并指出这个字符包含多少个字节。多字节串的其余字节都在0×80到0xBF范围里。这使得重新同步非常容易,并使编码无国界,且很少受丢失字节的影响。下列字节串用来表示一个字符. 用到哪个串取决于该字符在 Unicode 中的序号.
U-00000000 – U-0000007F: 0xxxxxxxU-00000080 – U-000007FF: 110xxxxx 10xxxxxxU-00000800 – U-0000FFFF: 1110xxxx 10xxxxxx 10xxxxxxU-00010000 – U-001FFFFF: 11110xxx 10xxxxxx 10xxxxxx 10xxxxxxU-00200000 – U-03FFFFFF: 111110xx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxxU-04000000 – U-7FFFFFFF: 1111110x 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxxxxx的位置由字符编码数的二进制表示的位填入。越靠右的x具有越少的特殊意义。只用最短的那个足够表达一个字符编码数的多字节串。注意在多字节串中,第一个字节的开头“1”的数目就是整个串中字节的数目。
例如: Unicode字符U+00A9=1010 1001(版权符号)在UTF-8里的编码为:
11000010 10101001 = 0xC2 0xA9
而字符U+2260=0010 0010 0110 0000(不等于) 编码为:
11100010 10001001 10100000 = 0xE2 0×89 0xA0
这种编码的官方名字拼写为UTF-8,其中UTF代表UCS Transformation Format。请勿在任何文档中用其他名字(比如utf8或UTF_8)来表示UTF-8,当然除非你指的是一个变量名而不是这种编码本身。
在大约1993年之后开发的大多数现代编程语言都有一个特别的数据类型,叫做Unicode/ISO 10646-1字符。在Ada95中叫Wide_Character,在Java中叫 char。
ISO C也详细说明了处理多字节编码和宽字符(wide characters)的机制,1994年9月Amendment 1 to ISO C发表时又加入了更多。这些机制主要是为各类东亚编码而设计的,它们比处理UCS所需的要健壮得多。UTF-8是ISO C标准调用多字节字符串的编码的一个例子,wchar_t类型可以用来存放Unicode字符。

文章来源:
标签: IT
关键词: Unicode, ISO 10646, UCS, UTF8, UTF16, GBK, GB2312, 字符编码, 外码, 内码, 通用字符集, 国际标准化组织, 预作字符, 组合字符, 基本多语言面
创建日期: 2011-10-23
修改日期: 2011-10-23