现在的位置: 首页 > 综合 > 正文

字符编码问题详解—未完待续

2014年11月13日 ⁄ 综合 ⁄ 共 3514字 ⁄ 字号 评论关闭

引言:

字符编码是计算机技术的基石,想成为顶级的计算机大师,熟练应用计算机技术,就必须要熟练懂得一些常用字符编码,了解其他的一些非常用字符编码方法的知识。最近在做中文域名注册系统,中文字符的编码问题就围绕在我脑海里面,这其中的转换关系,也不是件简单的事情,基于此,我要彻底搞明白这些编码的问题,并把其中的转换关系,以及域名相关的编码要求都要搞清楚。林语堂先生说过:一件事情或工具,只知道怎么用,而不清楚其中的道理,实在不是件高明的事(义译)。借用一下这个文人的话,表达我想彻底搞定字符编码问题的决心吧。

 

ASCII:(American Standard Code for Information Interchage:美国信息互换标准代码)

         是基于拉丁字母的一套电脑编码系统。它是现今最通用的单字节编码系统,并等同于国际标准:ISO/IEC 646。主要基于拉丁字母编码,是标准的单字节字符编码方案,用于基于文本的数据,供不同计算机在相互通讯时用作共同遵守的西文字符编码标准。

我们知道,在计算机内部,所有的信息最终都表示为一个二进制的字符串。每一个二进制位bit)有0和1两种状态,因此八位二进制就可以组合出256中状态,这被称为一个字节(byte)。也就是说,一个字节一共可以表示出256中不同的状态,每一个状态对应一个符合,就是256个符号,从00000000到11111111。

上个世纪60年代,美国制定了一套字符编码,对英语字符与二进制位之间的关系,做了统一规定。这被称为ASCII码,一直沿用至今。

       ASCII码一共规定了128个字符的编码,比如空格“SPACE”是32(二进制00100000),大写的字母A是65(二进制01000001)。这128个符号(包括32个不能打印出来的控制符号),只占用了一个字节的后面7位,最前面的1位统一规定为0。

 同时还要注意,在标准ASCII中,其最高位(b7)用作奇偶校验位。所谓奇偶校验,是指在代码传送过程中用来检验是否出现错误的一种方法,一般分奇校验和偶校验两种。奇校验规定:正确的代码一个字节中1的个数必须是奇数,若非奇数,则在最高位b7添1;偶校验规定:正确的代码一个字节中1的个数必须是偶数,若非偶数,则在最高位b7添1。

后128个称为扩展ASCII码,目前许多基于x86的系统都支持使用扩展(或“高”)ASCII。扩展 ASCII 码允许将每个字符的第 8 位用于确定附加的 128 个特殊符号字符、外来语字母和图形符号。

 

问题提出:

         英语用128个符号编码就够了,但是这样不能满足其他说英语国家的需求,比如英国的英镑£符号在ASCII码中就没有体现。并且用来表示其他语言,128个符号是不够的。比如,在法语中,字母上方有注音符号,它就无法用ASCII码表示。于是,一些欧洲国家就决定,利用字节中闲置的最高位编入新的符号。比如,法语中的é的编码为130(二进制10000010)。这样一来,这些欧洲国家使用的编码体系,可以表示最多256个符号。

         但是,这里又出现了新的问题。不同的国家有不同的字母,因此,哪怕它们都使用256个符号的编码方式,代表的字母却不一样。比如,130在法语编码中代表了é,在希伯来语编码中却代表了字母Gimel (ג),在俄语编码中又会代表另一个符号。但是不管怎样,所有这些编码方式中,0—127表示的符号是一样的,不一样的只是128—255的这一段。

         至于亚洲国家的文字,使用的符号就更多了,汉字就多达10万左右。一个字节只能表示256种符号,肯定是不够的,就必须使用多个字节表达一个符号。比如,简体中文常见的编码方式是GB2312,使用两个字节表示一个汉字,所以理论上最多可以表示256x256=65536个符号。因此其他编码方式及标准的提出,成为必要。

 

汉字编码:

         一.简体字

1.      GBK:汉字国际扩展码,基本上采用了原来GB2312-80所有的汉字及码位,并涵盖了原Unicode中所有的汉字20902,总共收录了883个符号,21003个汉字及提供1894个造字码位,又由于GBK同时也涵盖了Unicode所有CJK汉字,所以也可以和Unicode做一一对应。GBK编码是中国大陆制订的、等同于UCS的新的中文编码扩展国家标准。GBK工作小组于1995年10月,同年12月完成GBK规范。该编码标准兼容GB2312,简、繁体字融于一库。GBK码对字库中偏移量的计算公式为:

[(GBKH-0xB0)*0x5E+(GBKL-0xA1)]*(汉字离散后每个汉字点阵所占用的字节)

2.      GB2312:是中华人民共和国国家汉字信息交换用编码,全称《信息交换用汉字编码字符集——基本集》,由国家标准总局发布,1981年5月1日实施,通行于大陆、新加坡等地也使用此编码。GB码共收录6763个简体汉字、682个符号,其中汉字部分:一级字3755,以拼音排序,二级字3008,以偏旁排序。整个字符集分成94个区,每区有94个位。每个区位上只有一个字符,因此可用所在的区和位来对汉字进行编码,称为区位码。这个码是唯一的,不会有重码字。把换算成十六进制的区位码加上2020H,就得到国标码。国标码加上8080H,就得到常用的计算机机内码。同时,GB
2312收录了包括拉丁字母、希腊字母、日文平假名及片假名字母、俄语西里尔字母在内的682个全角字符。GB 2312的出现,基本满足了汉字的计算机处理需要,它所收录的汉字已经覆盖中国大陆99.75%的使用频率。对于人名、古汉语等方面出现的罕用字,GB 2312不能处理,这导致了后来GBK及GB 18030汉字字符集的出现。GB 2312中对所收汉字进行了“分区”处理,每区含有94个汉字/符号。这种表示方式也称为区位码。01-09区为特殊符号。16-55区为一级汉字,按拼音排序。56-87区为二级汉字,按部首/笔画排序。10-15区及88-94区则未有编码。举例来说,“啊”字是GB2312之中的第一个汉字,它的区位码就是1601。在使用GB2312的程序中,通常采用EUC储存方法,以便兼容于ASCII。浏览器编码表上的“GB2312”,通常都是指“EUC-CN”表示法。每个汉字及符号以两个字节来表示。第一个字节称为“高位字节”(也称“区字节)”,第二个字节称为“低位字节”(也称“位字节”)。“高位字节”使用了0xA1-0xF7(把01-87区的区号加上0xA0),“低位字节”使用了0xA1-0xFE(把01-94加上
0xA0)。由于一级汉字从16区起始,汉字区的“高位字节”的范围是0xB0-0xF7,“低位字节”的范围是0xA1-0xFE,占用的码位是 72*94=6768。其中有5个空位是D7FA-D7FE。例如“啊”字在大多数程序中,会以两个字节,0xB0(第一个字节) 0xA1(第二个字节)储存。区位码=区字节+位字节(与区位码对比:0xB0=0xA0+16,0xA1=0xA0+1)。

3.      GB18030:是我国继GB2312-1980和GB13000-1993之后最重要的汉字编码标准,是我国计算机系统必须遵循的基础性标准之一。

4.      HZ: HZ是一种INTERNET上常见的编码方案之一,它只对高位为1的字符(如汉字的双字节内码)进行编码,具体方法是将最高位屏蔽,只保留低7位,并将经过变换后的部分用符号~{和~}括起来,解码的时候只需将括号对内的部分高位置为1就可以正确地还原了。

5.      ISO-2022-CN:(暂时不考虑)

二.繁体字

1.  Big5:BIG-5码是通行于台湾、香港地区的一个繁体字编码方案,俗称“大五码”。地区标准号为:CNS11643,这就是人们讲的BIG-5码。

2.  Big5-HKSCS:

3.  EUC-TW: EUC-TW本来是台湾使用的其中一个汉字储存方法,以CNS11643字表为基础。但是台湾普遍使用大五码,EUC-TW甚少使用。

Unicode:(其实现方式)

1.      UTF-8

2.      UTF-16

3.      UTF-16LE

4.      UTF-16BE

5.      UTF-32

6.      UTF-32LE

7.      UTF-32BE

8.      UCS-2(USC-2只能用存储两个字节的Unicode,超过这一范围的符号,它不能表示。)

Base64/32:

Raix-64

PunyCode:

整数编码:

浮点数编码:

抱歉!评论已关闭.