彻底理解Gb2312、Gbk和Gb18030转载此文请联系Linux开发那些事儿公众号。在日常工作的过程中,字符编码的问题常常让人头疼。本文将回顾GB2312、GBK、GB18030的相关知识以及它们与Unicode的关系。简介GB23121980年,我国发布了第一个汉字编码标准,即GB2312,全称?,通常简称为GB(“国标”汉语拼音首字母),共有6763个常用汉字和字符包括在内。次年5月实施,满足99%汉字日常使用要求GBK由于GB2312标准发布后,部分汉字进行了简化,因此在人名、繁体字、日文、韩文中也有部分汉字所以,在GB2312的基础上,又增加了这些字符,形成了GBK,全称《汉字内码扩展规范》,收录了20000多个汉字和汉字。完全兼容GB2312。GBK于1995年发布,但只是一份《技术规范》的指导性文件,不属于国家标准GB18030。GB18030的全称是《信息技术 中文编码字符集》,包含7万多个汉字和汉字。它增加了中文汉字、日文、韩文和少数民族文字,在GBK的基础上,完全兼容GB2312,基本兼容GBKGB18030已经发布了两个版本,第一个版本发布于2000年,称为GB18030-2000,第二版发布于2005年,称为GB18030-2005编码方式,ASICII、GB2312、GBK、GB18030之间的关系如下图所示:GB2312兼容ASICII编码,GBK兼容GB2312编码,GB18030兼容GB2312编码和GBK编码,在现实生活中,我们使用的汉字99%都属于GB2312编码范围,请问每种GB2312编码对应的是哪一种?对于汉字,请se参考GB2312简体中文编码表,GBK编码请参考GBK编码表,GB18030请参考GB18030-2005文档GB2312编码GB2312将每个汉字编码成两个字节,第一个字节为高字节,第二个字节是GB2312的低位字节。为了兼容ASICII,需要对代码进行转换,避免与ASICII码重叠。转换过程涉及区号和国标码的概念。下面介绍转换成内码区码GB2312汉字分区的过程,每个分区包含94个汉字或汉字。共有94个区。每个汉字或汉字对应一个分区号和分区内的一个位置号,称为位置码。例如:汉字“中&曲”哦;字的分区号为54,分区中的位置号为48,所以“中”字的位置码为5448国标码国标码又称交换码,用于交换文件。在早期,不同的操作系统可能使用不同的内码。如果他们要交换文件,就会出现乱码。当时的解决方案是先将exchangecode转换成exchangecode再进行文件交换。代码交换代码是比较早的方案。目前,大多数系统使用内码作为交换码。ASICII码为0-31的32个字符为不可显示字符。为了避免与这些字符的码位冲突,将分区号在分区中的位置号上加32,将转换后的结果称为国标码。例如:汉字“中”的分区号为54,分区中的位置号为48,加上32后分区号为54+32=86,,分区中的位置号为48+32=80,所以“中”的国标码是8680。“中”字的国标码和ASICII码还是有重叠的,比如“中”的国标码是8680,对应第一个字节为86,第二个字节为80,在ASICII码中分别代表大写字母V和大写字母P,无法区分是一个汉字还是两个字母。一点,将国标码中每个字节的最高位设置为1,相当于每个字节加128(2的7次方),还是以“中”字为例,其国标码就是8680,加上128后,第一个字节是86+128=214,第二个字节是80+128=208,转成十六进制是0xD60xD0(214的十六进制是0xD6,208的十六进制是0xD0)国标码每个字节加128后,得到国标码的内码,简称内码。汉字在计算机中以内码的形式存储和传输。区号和国标码主要是说明汉字内码是如何一步步发展起来的。可以看出,内码是通过汉字的区号+32+128得到的,进一步简化,区号+32+128=区号+160=区号+0xA0(128的十六进制),所以内码=区号+0xA0例如:"中”的位置码是5448,对应的十六进制数是0x360x30,所以它的内码是(0x36+0xA0)(0x30+0xA0),即0xD60xD0。对于汉字的位置码,请参考:汉字区位码GB2312的有效编码范围如下图所示,上图中红色一栏表示ASICII的编码范围,绿色一栏表示GB2312的编码范围。GBK编码和GB2312一样,GBK也是双字节编码,为了向下兼容GB2312,GBK使用了GB2312没有使用的编码区,总编码范围为:第一个字节0x81–0xFE,第二个字节0x40–0xFE,具体编码范围细分如下上表,红色一栏在GBK中,包括了GB2312和ASICII的编码范围,它们的编码范围保持不变,绿色一栏是GBK新编码范围,紫色条为用户自定义编码范围.GB18030编码不同于GBK,GB18030是一个变长的多字节字符集,每个单词或字符可以由一个、两个或四个字节组成,因此它的编码空间非常大,最多可容纳161万个人物。由于需要兼容GBK,四个字节中的前两个字节与GBK编码一致。GB18030的具体编码范围如下:GB18030与UnicodeGB18030与Unicode相当于两个独立的编码系统。它们都对世界上的大部分字符进行编码,并为每个字符赋予一个唯一的编号。同一个字符,GB18030和Unicode对应的数字是不同的。例如汉字“中”的GB18030编码为0xD6D0,对应的Unicode编码单元为0x4E2D。从这一点来看,可以认为GB18030是Unicode格式的转换注:Unicode的编码格式真的可以看成是Unicode转换格式,所以严格来说GB18030并不是真正的Unicode转换格式。GB18030既是字符集又是编码格式,即字符集中字符的个数和存储的编码所用的数字是完全一样的,而Unicode只是一个字符集,只规定了唯一的数字字符,其存储为其他编码格式,如UTF8、UTF16等。由于GB18030和UUnicode可以代表世界上绝大部分的字符。为什么需要两套字符集?一套不是更有利于信息的传播吗?1、Unicode出现之前,并没有统一的字符编码,每个操作系统都有自己的一套编码标准。比如需要在earlywindow上安装字符集来支持中文。这里的字符集是微软制定的标准。它将无法更改为其他系统。2、对于大多数汉字,使用GB18030编码,只需要两个字节,如果使用UTF8编码,则需要三个字节,所以使用GB18030来存储和传输更节省空间。ASICII、GB2312、GBK、GB18030、UTF8的关系如下:从图中可以看出,GB2312、GBK、GB18030、UTF8都兼容ASICII全角和半角字符。使用输入法输入字符时,有全角和半角之分。下面列出了部分字符的全角和半角屏幕截图。半角是ASICII码中的一个字符,对应的编码范围是0x00-0x7F。每个字符占用一个字节。全角是GB2312中的一个字符,每个字符占两个字节。字节,编码范围和半角字符范围不重叠。对于汉字,没有全角和半角之分。编码为0x40,占用一个字节。通过内码输入汉字的方法有时需要输入一些特殊字符,如带圆圈的数字①,一般需要借助输入法的小键盘输入。快速输入法:按住Alt键,输入字符内码的小数点,输入后松开Alt键。例如输入带圆圈的数字②第一步,找到圆圈中数字为2的字符的编码0xA2DA,十进制为416902,按住Alt键,输入41690,松开Alt键3,后输入,此时会出现字符②一般LinuxSSH连接工具或Windows上的记事本都支持内码输入
