前面的一些篇章更多谈论了Unicode的相关话题,虽然也有提到GBK等编码,但都没细说,这里打算系统说一下。GB系列包括GB2312,GBK,GB18030.
最早的是GB2312,我们从它开始说起。 GB2312以下为一简介(官方文档见:http://gbread.sac.gov.cn/bzzyReadWebApp/standardresources.action?m=readFile&bzNum=GB%202312-1980&flag=1,用IE打开,它要安装一个ActiveX我插呀件~):
作为一个编码字符集而言,前面也曾说到,它采用了所谓的二维区位编号,下面是一个概览图: 它是一个94*94的表格,理论上有94*94=8836个空间。 横的叫区,竖的叫位,总共94个区,区和位的编号都从1开始。可以看到粗略有三大部分。 94个区1. 中间黑色的主体部分即是汉字区了,具体为16-87区,共87-16+1=72个区,理论空间为72*94=6768.
2. 最下面的88-94区是有待进一步标准化的空白区。 3. 关于前面的01-15区,下图为概览图左上角的局部放大图: 1. 01-09区为符号、字母、日文假名等,部分区还有空白位。
2. 10-15区也是有待进一步标准化的空白区。 各区的一个具体情况:
区位码在上图中还标出了一个汉字“啊”,它就是GB2312方案中的天字第一号汉字,它处于16区01位上,所以它的区位码即是1601.
国标码将区位码的区和位分别加上32(=0x20)就得到了国标码。
GB2312方案规定,对上述表中任意一个图形字符都采用两个字节表示,每个字节均采用七位编码表示。
但为何不直接采用区位码呢?为什么要加32呢?你也许还记得前面说到ASCII时,前面32个字符是控制码,中文系统自然也不能少了这些控制码,为了不与这些控制码冲突,加上32就能跳过它们了。
国标码的定位实际应该是与ASCII一致的,是作为国家信息交换的标准码。从设计上看,它并没打算兼容ASCII,它已经把ASCII中的字符收录了过来,不过是作为所谓的全角字符来看待,但全角英文显示效果其实是很差的,下面是全角英文的一个示例:
显得非常不紧凑,最终,一种能兼容ASCII的存储方案得到了广泛采纳,这就是所谓的机内码了。 机内码将国标码高低字节分别加上0x80(=128)就得到了机内码(有时又叫交换码)。128的二进制形式为10000000,加128,简单地讲,就是把国标码最高位置成1.至于为什么要这样呢?我想你应该也清楚了,就是要兼容ASCII,ASCII最高位为0,国标码加128后,高低字节的最高位都成了1,这样就与ASCII区分开来。
如果从区位码算起,那么则是加上0x20+0x80=32+128=160=0xA0,也即区位码的区和位分别直接加上0xA0即可得到机内码,如下图所示: 如果你新建一个文本文件,录入“啊”字,以GB2312编码方式保存(使用GBK即可,它兼容GB2312),再用十六进制查看,你会发现使用的是机内码: 使用代码的测试也可验证这一点: 虽然我们常把GB2312称为国标码,但我们应该清楚,实际存储使用的是机内码,通常说到GB2312编码时指的就是这个机内码了。它能兼容ASCII,是一种变长的编码方案,对ASCII中的字符(也即所谓的“半角西文字符”)采用一字节编码,最高位为0;对区位表中的字符采用两字节编码,且每字节最高位均为1,以此区分。
下面是一个混合了汉字,半角字母a和全角字母a的编码示例,共5个字节:
你可能会想,那国标码还有什么用?
下面是三种码在256*256坐标中的位置的一个示意图: GBKGBK是对GB2312的一个扩展,兼容GB2312,因此也兼容ASCII,也是一个变长编码方案。下面是一个简介:
GBK是国家有关部门与一些信息行业企业等一起合作推出的方案,但并未作为国家标准发布,只是一个事实上的标准,一个过渡方案,为GB18030标准作的一个准备。 首字节(lead byte)下面是Windows Code page: 936 (GBK),第一字节的概况(来自http://msdn.microsoft.com/en-US/goglobal/cc305153.aspx)
1. 上面部分是兼容ASCII单字节编码。 2. 下面阴影部分是双字节编码中的第一个字节,表中作为超链接,可以点击进去查看具体内容。
第二字节前面说到“啊”的机内码是B0A1,我们点击B0(上图中红色小框部分)去查看一下(来自http://msdn.microsoft.com/en-US/goglobal/gg675356): 1. “啊”位于A1处,所以它是兼容GB2312的。而前面的那些字符就是GBK扩展的了。
2. 第二字节从0x40开始,不是从0x00也不是从0x80开始。表格只有12行。
3. 另外0x7F和0xFF两处保留未定义。
GBK还是UTF-8?GBK使用两字节保存中文,也能兼容ASCII,而对常用汉字,UTF-8都是采用三字节编码,因此无论是全中文还是中英文混合的情况,GBK保存的效率都要好于UTF-8.
但它也有些不好的地方,比如它不能支持一些国际性的文字,在国际化,通用性方面它肯定不如UTF-8;就汉字而言,由于容量空间的限制,它也无法收录更多的汉字了。
GB18030GB18030前后发布了两个标准,最新的是2005年发布的GB 18030-2005(《信息技术 中文编码字符集》),2000年还有一版GB18030-2000,更多了解可参考百度百科http://baike.baidu.com/view/889058.htm,官网见http://gbread.sac.gov.cn/bzzyReadWebApp/standardresources.action?m=readFile&bzNum=GB 18030-2005&flag=1,(注:这个文件比较大) 对于多数用户而言,无需了解太多,这里也不打算详细介绍,下面是一些简介(针对最新的GB18030-2005):
对于普通用户,超大字符集很少用到,通常情况下,如Windows系统下你可能要安装GB18030的相关插件才能处理及显示那些增补的字符,一般系统默认情况也不会安装能支持完整显示GB18030全体字符的字体。
关于GB系列的编码就说到这里。 |
|