ASCII/Unicode/UCS/UTF/GB字符编码

来源:互联网 发布:淘宝详情图尺寸大小 编辑:程序博客网 时间:2024/04/30 04:24

    ASCII码是7位编码,编码范围是0x00-0x7F。ASCII字符集包括英文字母、阿拉伯数字和标点符号等字符。其中0x00-0x20和0x7F共33个控制字符。
    1.字节序列
    
首先简要说明下big endian和little endian:big endian和little endian是CPU处理多字节数的不同方式。例如“汉”字的Unicode编码是6C49。那么写到文件里时,究竟是将6C写在前面,还是将49写在前面?如果将6C写在前面,就是big endian。如果将49写在前面,就是little endian。字节序列标志称为BOM,BOM的用处是用在字符编码里作以标记。
    2.字符编码标准
    
(1)ISO 10646:通用字符集(Universal Character Set,UCS)是由ISO制定的ISO 10646(或称ISO/IEC 10646)标准所定义的标准字符集。也就是说ISO 10646标准字符对应的就是UCS。通用字符集又称Universal Multiple-Octet Coded Character Set。
    (2)Unicode:Unicode(统一码、万国码、单一码、标准万国码)是一种字符编码也是一种标准。Unicode依照通用字符集(Universal Character Set)的标准来发展。Unicode是由非营利机构统一码联盟开发并监督。
    3. Unicode编码和UCS
    
最初统一码联盟和国际标准化组织指定了不同的标准Unicode和ISO 10646。后来两者都认识到世界不需要两个不兼容的字符集。现在Unicode和UCS字符集的编码已经统一。UCS的有两种编码方案(也可以说实现方式):UCS-2(用两个字节编码)和UCS-4(用4个字节编码)。UCS-4根据最高位为0的最高字节分成2^7=128个group。每个group再根据次高字节分为256个平面(plane)。group 0的平面0被称作BMP(Basic Multilingual Plane)——基本多文种平面。将UCS-4的BMP去掉前面的两个零字节就得到了UCS-2。每个平面有2^16=65536个码位。Unicode计划使用了17个平面,一共有17*65536=1114112个码位。用十六进制就是0-0x10FFFF。这个编码也得到了ISO 10646的认可。而且ISO 10646也承诺不会为超出这17个平面的字符赋值。(在Unicode 5.0.0版本中,已定义的码位只有238605个,分布在平面0、平面1、平面2、平面14、平面15、平面16。其中平面15和平面16上只是定义了两个各占65534个码位的专用区(Private Use Area),分别是0xF0000-0xFFFFD和0x100000-0x10FFFD。所谓专用区,就是保留给大家放自定义字符的区域,可以简写为PUA。当然,每个平面的字符还没有填满(一些空白),所以许多平面的字符集还在扩展中。随着Unicode版本的不断更新,字符集也在不断丰富和完善。
    通过以上的阐述可以知道,虽然理论上UCS可以达到2^31(因为最高位是0,不然就是2^32个)。但是实际上Unicode根据实际采用的是0-0x0010FFFF编码的字符,省略高字节就是0-0x10FFFF个。而且ISO也认证了就用0-0x10FFFF。在这个范围内的字符编码Unicode和UCS是一致的,但是他们有字形上的差异。如Unicode一般都会采用有关字码最常见的字型,但ISO 10646一般都尽可能采用Century字型。
    4. Unicode实现方式
    
既然ISO 10646同意不再为超过0x10FFFF的字符赋值,也就是Unicode的实现方式也就是UCS的实现方式——UTF(Unicode/UCS Transformation Format),主要有UTF-8、UTF-16、UTF-32。
    (1)UTF-8:
    
UTF-8是Unicode的一种变长字符编码又称万国码,由Ken Thompson于1992年创建。现在已经标准化为RFC 3629。UTF-8用1到6个字节编码Unicode字符,如下表:

UNICODE

UTF-8

0000 0000 - 0000 007F

0XXX XXXX

0000 0080 - 0000 07FF

110X XXXX ,10XX XXXX

0000 0800 - 0000 FFFF

1110 XXXX ,10XX XXXX ,10XX XXXX

0001 0000 - 001F FFFF

1111 0XXX ,10XX XXXX
10XX XXXX ,10XX XXXX

0020 0000 - 03FF FFFF

1111 10XX ,10XX XXXX ,10XX XXXX
10XX XXXX ,10XX XXXX

0400 0000 - 7FFF FFFF

1111 110X ,10XX XXXX ,10XX XXXX
10XX XXXX ,10XX XXXX ,10XX XXXX

    由上可以看出UTF-8包含了超出0x10FFFF的字符,这是理论编码方案,实际上按照Unicode标准,用到的是下面的方案:

    000000 - 00007F ║ 0xxxxxxx
    000080 - 0007FF ║ 110xxxxx 10xxxxxx
    000800 - 00FFFF ║ 1110xxxx 10xxxxxx 10xxxxxx
    010000 - 10FFFF ║ 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx

    UTF-8兼容ASCII,且UTF不涉及字节序,但是BOM可以用EF BB BF来标记UTF-8,也就是给UTF-8编码加上BOM:EF BB BF。其实每一种BOM都起到标识和字节序的作用,以下的解释不难发现。
    (2)UTF-16:
    
也是Unicode的标准实现方式,也就是在具体平台下UTF-16就是Unicode的意思(因为Unicode默认采取就是UTF-16)。它定义于ISO/IEC 10646-1的附录Q,而RFC2781也定义了相似的做法。在基本多语言平面(Basic Multilingual Plane, BMP又称第0平面),使用2个字节表示,在此之外的字符(其他16个平面内的字符也称辅助平面字符),则使用4个字节表示。
    具体的编码方式是:
    a.如果字符编码U小于0x10000,也就是十进制的0到65535之内(这里是第0平面的字符),则直接使用两字节表示;其中从0XD800到0XDFFF之间的区段是没有使用的,用来代理辅助平面的字符,又称为代理区。
    b.如果字符编码U大于0x10000,由于UNICODE编码范围最大为0x10FFFF,从0x10000到0x10FFFF之间共有0xFFFFF个编码,也就是需要20个bit就可以标示这些编码。用U'表示从0-0xFFFFF之间的值,将其前10 bit作为高位,后10 bit作为低位。这里使用代理区将高位与0xD800进行逻辑or操作,将低位与0xDC00进行逻辑or操作。
    D800-DBFF ║ High Surrogates ║ 高位替代
    DC00-DFFF ║ Low Surrogates  ║ 低位替代
    高位替代+低位替代(高位替代的两字节大在前,小在后是大尾,低位替代类同,而不是高位替代和低位替代的交换)就是4个字节(前两个字节一个组合,后两个一个组合)的实现方式。在C#环境下,每个char占两个字节,所以超出UCS-2的字符C#采取4个字节存储,这时候如果将其转化为字符数组,4字节的字符要用两个char存储,4字节读取时是每次读取两个字节,计算长度时4字节按照两个字符计算。因为字符的操作是按字节规则的。
    UTF-16可以看成是UCS-2的父集,在没有辅助平面字符时,它们是同一意思。UTF-16有涉及字节序和BOM(FF FE代表UTF-16LE(小尾),FE FF代表UTF-16BE(大尾))。
    3)UTF-32:
    
UTF-32大体和UCS-4相同,除了Unicode额外意涵(额外意涵就是节约字码空间)。UCS-4理论的取值:0-7FFFFFFF。UTF-32是UCS-4的子集,在0-0x10FFFF之前取值。
    UTF-32涉及字节序和BOM,这里和UTF-16不同,需要把四个字节方向排列。BOM标志为:UTF-32LE(小尾):FF FE 00 00;UTF-32BE(大尾):00 00 FE FF。UTF-32在0-10FFFF之间和UCS-4编码一致。
    5. Unicode和其他字符编码标准
    
其他字符集如:GB2312(中国简体中文字符标准)、GBK(对GB2312的扩展)、GB18030(对GBK的扩展)……。这几个是中国国家标准字符集(并在不断扩展中),这几个是反向兼容的,即后一个兼容上一个。还有其他国家的国家标准字符集。这些都是在对应某种语言的字符代码页。在操作系统中,这种字体一般采取一种转换机制转换成Unicode编码。现在的操作系统一般都采用Unicode统一码。Unicode码和GB码还有其他编码都兼容ASCII(准确说是ISO 8859-1标准)。其中Unicode在某些实现方式上字节与ASCII不对应,但转化后的整数是对应的。

原创粉丝点击