[资料库]字符编码(二):Unicode

多年来。计算机普遍采用美国信息交换标准代码(American Standard Code for Information Interchange,简称ASCII码)来表示字符。这些字符可以是字母。数字。标点符号和控制符。用这种编码来表示英文在内的字符不成问题的。但要表示其它语言文字如。阿拉伯文。中文。日文。维文。哈文…必须进行扩充。在1987年。Xerox Palo Alto研究中心的Joe Becker和Lee Collins。以及Apple公司的Mark Davis试图研究一种适用于多文种处理的字符编码。这种编码很快就得到了许多大公司的支持。这些公司都派代表参加Unicode研究组。Unicode的研究得到了较快的进展。由于Unicode集团的成员都是世界上的主要系统及软件制造商。所以Unicode很快就成为事实上的工业标准。

基于Unicode的系统允许使用65000个不同的字符。足以善盖世界所有语言的所有字母。外加数千种符号。

其中。General Scripts区单独收录了19种语言文字。包括ASCII,Latin1,Greek,Cyrillic,Armenian,Hedrew,Arabic,Devanagari,Bengali ,Gurmukhi,Gujarati,Oriya,Tamil,Telugu,Kannada,Malayalam,Thai,Lao,Tibetan,Georgian等语言文字之外。还包括汉语。日语和朝鲜语中的所有大量字符。

为了统一全世界各国语言文字和专业领域符号(例如数学符号、乐谱符号)的编码,ISO制定了ISO 10646标准,也称为UCS(Universal Character Set)。UCS编码的长度是31位,可以表示2的31次方个字符。如果两个字符编码的高位相同,只有低16位不同,则它们属于一个平面(Plane),所以一个平面由216个字符组成。目前常用的大部分字符都位于第一个平面(编码范围是U-00000000~U-0000FFFD),称为BMP(Basic Multilingual Plane)或Plane 0,为了向后兼容,其中编号为0~256的字符和Latin-1相同。UCS编码通常用U-xxxxxxxx这种形式表示,而BMP的编码通常用 U+xxxx这种形式表示,其中x是十六进制数字。在ISO制定UCS的同时,另一个由厂商联合组织也在着手制定这样的编码,称为Unicode(见上文所述),后来两家联手制定统一的编码,但各自发布各自的标准文档,所以UCS编码和Unicode码是相同的。

有了字符编码,另一个问题就是这样的编码在计算机中怎么表示。现在已经不可能用一个字节表示一个字符了,最直接的想法就是用四个字节表示一个字符,这种表示方法称为UCS-4或UTF-32,UTF是Unicode Transformation Format的缩写。一方面这样比较浪费存储空间,由于常用字符都集中在BMP,高位的两个字节通常是0,如果只用ASCII码或Latin-1,高位的三个字节都是0。另一种比较节省存储空间的办法是用两个字节表示一个字符,称为UCS-2或UTF-16,这样只能表示BMP中的字符,但BMP中有一些扩展字符,可以用两个这样的扩展字符表示其它平面的字符,称为Surrogate Pair。无论是UTF-32还是UTF-16都有一个更严重的问题是和C语言不兼容,在C语言中0字节表示字符串结尾,库函数strlen、strcpy等等都依赖于这一点,如果字符串用UTF-32存储,其中有很多0字节并不表示字符串结尾,这就乱套了。
UNIX之父Ken Thompson提出的UTF-8编码很好地解决了这些问题,现在得到广泛应用。UTF-8具有以下性质:

    *      编码为U+0000~U+007F的字符只占一个字节,就是0x00~0x7F,和ASCII码兼容。
    *      编码大于U+007F的字符用2~6个字节表示,每个字节的最高位都是1,而ASCII码的最高位都是0,因此非ASCII码字符的表示中不会出现ASCII码字节(也就不会出现0字节)。
    *      用于表示非ASCII码字符的多字节序列中,第一个字节的取值范围是0xC0~0xFD,根据它可以判断后面有多少个字节也属于当前字符的编码。后面每个字节的取值范围都是0x80~0xBF,见下面的详细说明。
    *      UCS定义的所有231个字符都可以用UTF-8编码表示出来。
    *      UTF-8编码最长6个字节,BMP字符的UTF-8编码最长三个字节。
    *      0xFE和0xFF这两个字节在UTF-8编码中不会出现。

具体来说,UTF-8编码有以下几种格式:

U-00000000 – U-0000007F:  0xxxxxxx
U-00000080 – U-000007FF:  110xxxxx 10xxxxxx
U-00000800 – U-0000FFFF:  1110xxxx 10xxxxxx 10xxxxxx
U-00010000 – U-001FFFFF:  11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
U-00200000 – U-03FFFFFF:  111110xx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx
U-04000000 – U-7FFFFFFF:  1111110x 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx

第一个字节要么最高位是0(ASCII字节),要么最高两位都是1,最高位之后1的个数决定后面有多少个字节也属于当前字符编码,例如111110xx,最高位之后还有四个1,表示后面有四个字节也属于当前字符的编码。后面每个字节的最高两位都是10,可以和第一个字节区分开。这样的设计有利于误码同步,例如在网络传输过程中丢失了几个字节,很容易判断当前字符是不完整的,也很容易找到下一个字符从哪里开始,结果顶多丢掉一两个字符,而不会导致后面的编码解释全部混乱了。上面的格式中标为x的位就是UCS编码,最后一种6字节的格式中x位有31个,可以表示31位的UCS编码,UTF-8就像一列火车,第一个字节是车头,后面每个字节是车厢,其中承载的货物是UCS编码。UTF-8规定承载的UCS编码以大端表示,也就是说第一个字节中的x是UCS编码的高位,后面字节中的x是UCS编码的低位。

例如U+00A9(©字符)的二进制是10101001,编码成UTF-8是11000010 10101001(0xC2 0xA9),但不能编码成11100000 10000010 10101001,UTF-8规定每个字符只能用尽可能少的字节来编码。

Unicode的优点是什么?
举一个最明显的例子就是Windows 2000/XP以及微软Office2000及其后的产品。因为这些软件都是Unicode内核,因此,无论何种文字,都可以在上面正常显示,而且是同屏显示。以前,简体中文的Word文件拿到英文版打开就会是乱码,简体中文的程序在Windows英文版上运行会出现乱码,而现在一切都解决了。

1.      各地的方言

            在中国,大陆最常用的就是GBK18030编码,除此之外还有GBK,GB2312,这几个编码的关系是这样的。

            * 最早制定的汉字编码是GB2312,包括6763个汉字和682个其它符号

            * 95年重新修订了编码,命名GBK1.0,共收录了21886个符号。

            * 之后又推出了GBK18030编码,共收录了27484个汉字,同时还收录了藏文、蒙文、维吾尔文等主要的少数民族文字。

现在WINDOWS平台必需要支持GBK18030编码。按照GBK18030、GBK、GB2312的顺序,3种编码是向下兼容,同一个汉字在三个编码方案中是相同的编码。

 

            * 台湾,香港等地使用的是BIG5编码

            * 日本:SJIS编码

 

2.UCS-2 与UCS-4

  Unicode的学名是"Universal Multiple-Octet Coded Character Set",简称为UCS。

  现在用的是UCS-2,即2个字节编码,而UCS-4是为了防止将来2个字节不够用才开发的。UCS-2也称为基本多文种平面。

  UCS-2转换到UCS-4只是简单的在前面加2个字节0。

  UCS-4则主要用于保存辅助平面,例如Unicode 4.0中的第二辅助平面

  20000-20FFF ~~~~~2F000-2FFFF

  总共增加了16个辅助平面,由原先的65536个编码扩展至将近100万编码。

3.      兼容codepage

  那么既然统一了编码,如何兼容原先各国的文字编码呢?

  这个时候就需要codepage了。

  什么是codepage?codepage就是各国的文字编码和Unicode之间的映射表。

  比如简体中文和Unicode的映射表就是CP936,

      以下是几个常用的codepage

            codepage=936 简体中文GBK

            codepage=950 繁体中文BIG5

            codepage=437 美国/加拿大英语

            codepage=932 日文

            codepage=949 韩文

            codepage=866 俄文

            codepage=65001 unicode UFT-8

你可能感兴趣的:(unicode)