字符编码简介 ASCII UTF-8 ISO8859-1
计算机中的一切都是以数字来表示的,字符同样如此。字符编码就是将字符集编码成为数字序列,以便能让计算机识别。各个地区和国家使用的语言有别,将本地使用的语言符号进行编码就得到本地编码字符集。例如西欧国家使用的本地编码是ISO8859-1,中国大陆和新加坡等地区使用本地编码是GB2312或GBK,中国港台地区使用的本地编码是BIG5,韩国和日本的本地编码分别是euc-kr和Shift_JIS。电脑的操作系统支持各种本地编码字符集,操作系统默认的本地编码和你所安装的操作系统语言版本是一致的。本地集只对本地使用的文字符号进行了编码,并不包括其他地区使用的文字,即使两个本地集中包含了相同的字符,这个字符的编码值也是不同的。例如“中”的GB2312或GBK编码值为“0xD6D0”,而BIG5编码值为“0xA4A4”。
全球信息交流与融合的趋势要求实现对本地字符集的统一,1984年4月ISO成立了工作组,针对各国文字、符号进行统一编码,这种编码成为Unicode。Unicode于1992年6月通过DIS(DrafInternationalStandard),V2.0版本于1996年发布。Unicode编码包括了符号6811个、汉字20902个、韩文11172个、等等。Unicode虽然实现了全球统一编码,但是在字符集数量和编码效率方面显然存在着不足,而UTF-8、UTF-16就是针对Unicode编码进行转换或扩充形成的编码,UTF是Unicode Translation Format的缩写。
[细节]
关于ASCII编码
ASCII编码是美国标准信息交换码,这种编码方式针对的是英文字符。ASCII编码使用一个字节对字符进行编码,而且字节的最高位都为0,因此ASCII编码的字符集大小是128个。由于英文字母仅有26个,再加上其他一些常用符号,总大小也不会超过128个,因此ASCII编码的空间是足够的。例如,字符“a”被编码为0x61,字符“b”被编码为0x62等等。注意,在有的时候ASCII泛指本地编码,例如文本编辑器UltraEdit中有诸如“ASCII转Unicode”的功能,这里的ASCII就泛指本地编码,如果本地编码是GBK,这个功能执行的就是GBK编码到Unicode编码的转换。
关于ISO8859-1编码
ISO8859-1是西欧语系国家通用的字符集编码,ISO8859-1使用一个字节对字符进行编码,编码值范围是0x00-0xFF。其中,0x00-0x1F用作控制字,0x20-0x7F表示字母、数字和符号这些图形字符,0xA0-0xFF作为附加部分使用。由于ASCII编码只使用了一个字节中的低7位,编码范围仅为0-127,虽然可以容纳英文字符和其他的一些符号,但是却不能包含除英文以外的其他西欧语言的字母,因此ASCII编码在西欧国家并不通用。针对这个问题ISO在ASCII编码的基础上进行了扩充,制定了ISO8859-1编码,ISO8859-1编码使用了一个字节的全部8位,编码范围是0-255,能包含西欧语系的所有字母和符号。
关于GB2312、GBK和BIG5编码
GB2312码是中华人民共和国国家汉字信息交换使用码,全称《信息交换使用汉字编码字符集-基本集》,由国家标准总局发布,1981年5月1日实施,中国大陆和新加坡等地使用此编码。GB2312收录了简化汉字、符号、字母、日文假名等共计7445个字符,其中汉字占6763个。GB2312将代码表分区94个区(0xA1-0xFE),对应第一个字节,每个区94个位(0xA1-0xFE),对应了第二字节,两个字节的值分别为区号的值和位号的值加32(0x20),因此也被称为区位码。GB2312的编码范7围是0x2121-0x777E,与ASCII有重叠,通常方法是将GB码的两个字节的最高位置1区别。
GBK是GB2312-80的扩展,向上兼容,包含了20902个汉字,编码范围是0x8140-0xFEFE,剔除高位0x80的字位,其他字符都可以一一映射到Unicode2.0。GB18030-2000(GBK2K)在GBK的基础上增加了藏、蒙等少数民族的字符,GBK2K从根本上解决了字位不够、字形不足的问题。GBK2K首先要求实现能够完全映射到Unicode3.0标准的所有字形,现在还没有任何一个操作系统支持GBK2K。
BIG5码被称为大五码,是中国港台地区使用的字符编码方式。TW-BIG5码将所有字分为两大群,即常用字区和次常用字区,每个字区分都采用笔画排序,同笔画的字依部首排序。TW-BIG5每个字由两个字节组成,第一个字节编码范围是0xA1-0xF9,第二个字节编码范围是0x40-0x7E和0xA1-0xFE,共计收入13868个字,其中包括5401个常用字、7652个次常用字、7个扩充字、以及808个其他符号。
关于Unicode编码
ISO(国际化标准组织)将全世界所有的符号进行统一编码,称为Unicode编码。Unicode编码的字符占用两个字符的大小,对于ASCII码表示的字符,Unicode只是简单的在ASCII码原来的一个字节码值上增加一个所有位全为0的字节。Unicode使用两个字节编码,因此能表示的字符集最大为65536,另外Unicode中还保留两千多个数值未用于字符编码。由于Unicode编码的空间有限,只能包含各个地区常用的字符而非所有字符,因此,在相当长的一段时间里,本地化字符编码和Unicode编码将共存。
关于UTF-8和UTF-16编码
UTF-8和UTF-16编码仍然属于Unicode编码,它们是在Unicode编码基础上进行了转换或扩展。例如在Windows XP和2000操作系统中,Unicode编码指的就是UTF-16编码。
UTF-8编码是将Unicode编码中不同范围的字符采用不同的字节进行编码,对于ASCII编码的字符仍使用一个字节进行编码,UTF-8编码完全兼容ASCII编码。与Unicode想比较,UTF-8编码使得英文文档的占用空间减小了一半,因此UTF-8颇受英语系国家的青睐。除此之外,UTF-8编码中不会出现值为0x0000的数据,这样避免了和某些程序语言产生冲突,而UTF-8编码的补充位使得数据能够被方便的检测出传输过程中是否发生错误。通常,UTF-8编码都使用“EF BB BF”三个字节数据作为文件开头。
Unicode编码和UTF-8编码结构的对应关系如下:
? Unicode编码值 UTF-8编码结构
? \u0001 - \u007E??? 0XXXXXXX
? \u0080 - \u07FF 和 \u0000 110XXXXX 10XXXXXX
? \u0800 - \uFFFF??? 1110XXXX 10XXXXXX 10XXXXXX
Unicode编码与UTF-8编码的转换如下(U8代表UTF-8编码,U代表Unicode编码):
1) 位于Unicode编码空间 \u0001-\u007F之间的字符(即编码使用位小于8位的字符),UTF-8采用一个字节对这些字符进行编码。直接将Unicode编码的低位取出就得到了UTF-8编码。转换过程可表示为:U8 = (byte)U。
2) 位于Unicode编码空间\u0080-\u07FF之间的字符以及\u0000表示的字符(即编码使用位为8-11位的字符,以及空字符),UTF-8采用两个字节对这些字符进行编码。这时候,将Unicode编码转换为UTF-8编码的方法是:将Unicode编码的低6位取出,在前面补充“10”作为低字节;将7-11位取出,在前面补充“110”作为高字节。转换过程可表示为:U8 = [(byte)(0xC0 | (0x01F & (U>>6)),(byte)(0x80 | (0x3F & U)]。
3) 位于Unicode编码空间\u080-\uFFFF之间的字符(即编码使用位为12-16位的字符),UTF-8采用三个字节对这些字符进行编码。这时候,将Unicode编码转换为UTF-8编码的方法是:将Unicode编码的低6位取出,在前面补充“10”作为低字节;将7-12位取出,在前面补充“10”作为中字节;将13-16位取出,在前面补充“1110”作为高字节。转换过程可表示为:U8 = [(byte)(0xE0 | (0x0F & (U>>12))),(byte)(0x80 | (0x03F & (U>>6)),(byte)(0x80 | (0x3F & U)]。
UTF-16编码在Unicode基础上进行了一些细节上的扩充,增加了对Unicode编码没有包括的字符的表示方式。UTF-16对Unicode的扩充并没有影响Unicode编码中的原有字符,容易看出Unicode是UTF-16的子集。Unicode编码将0xD800-0xDFFF区间的数值保留,被称为代理区间,区间共包含2048个数值,其中0xD800-0xD6FF是高半代理区,0xDC00-0xDFFF是低半代理区。UTF-16编码就是在Unicode编码基础上利用代理区扩充字符编码的机制。UTF-16编码从两个区域分别取一个编码,组成一个4字节的代理对来表示一个编码字符,就能够在Unicode基础上扩充了1024*1024个字符。UTF-16足够用来编码全球的所有字符,微软从Windows2000开始支持UTF-16编码。
关于Little-Endian和Big-Endian
在不同体系的计算机系统中,编码的Unicode字符在内存中存储的顺序是不同的。使用Inter生产的CPU的计算机,内存中数据存储通常是低字节在前,高字节在后,这种存储方式被称为Little-Endian。在对于一些计算机,内存中数据存储通常是高字节在前,低字节在后,这种存储方式被称为Big-Endian。
UTF-16编码的文件通常在文件开头用字符标志出使用的存储方式:若文件开头是“0xFF 0xFF”,表示文件其余部分是Little-Endian的 UTF-16编码;若文件开头是“0xFE 0xFF”,表示文件其余部分是Big-Endian的 UTF-16编码