汉字编码知识点
ASCII码是西欧编码的方式,采取7位编码,所以是2^7=128,共可以表示128个自负,包括34个字符,(如换行LF,回车CR等),其余94位为英文字母和标点符号及运算符号等。在计算机中,一个ASCII码占8位,最高位(bit7)用作奇偶校验。奇校验规则:正确的代码一个字节中1的个数必须是奇数,若非奇数,则在最高位b7补一个1;偶校验规则:正确的代码一个字节中1的个数必须是偶数,若非偶数,则在最高位b7补一个1。
为了识别双字节的字符,比如汉字或日文韩文等都是占用2个字节的,每字节高位为1,而一般细纹字符只有一个字节,七位有效编码,高位为补位用,通常是0.汉字编码格式通常称为10格式,一个汉字占2个字节,但只表示一个字符。
一、GB2312编码
GB2312共收录了6763个汉字,其中一级汉字3755个,二级汉字3008个,这里的一级汉字和二级汉字是根据编码的区位来区分的;另外,还收录了包括拉丁字母、希腊字母、日文平假名及片假名字母、俄罗斯语西里尔字母在内的682个全形字符。
GB2312区位码:
GB2312对所收汉字进行了”区分“处理,美区含有94个汉字/符号。这种表示方式也称为区位码。
(1)01-09区为特殊符号
(2)16-55区为一级汉字,按拼音排序
(3)56-87区为二级汉字,按部首/笔画排序
(4)10-15区及88-94区则未有编码
举例来说,“啊”字是GB2312之中的第一个汉字,它的区位码就是1601。字节编码,通常采用EUC储存方法,以便兼容于ASCII。每个汉字及符号以两个字节来表示。 第一个字节称为“高位字节”,第二个字节称为“低位字节”。 “高位字节”使用了0xA1-0xF7(把01-87区的区号加上0xA0),“低位字节”使用了0xA1-0xFE(把01-94加上0xA0)。例如“啊”字在大多数程序中,会以0xB0A1储存(与区位码对比:0xB0=0xA0+16,0xA1=0xA0+1)。
所以GB2312编码中汉字区码的十进制是从176到247,位码是从161到255.之所以存储了6763小于82*94=6768,是因为在区码为215,位码为250-254之间共五个编码没有汉字编码,所以6768-5=6763个。
其编码范围:A1A1-FEFE,其中汉字的编码范围为B0A1(十进制283159)-F7FE(十进制406662),第一字节0xB0-0xF7(对应区号:16-87),第二个字节0xA1-0xFE(对应位号:01-94)。
GB2312编码规则:
(1)2字节编码,高位为0xA1-0xF7,低位为0xA1-0xFE
(2)汉字区域,高位为0xB0-0xF7,低位为0xA1-0xFE
(3)特殊符号,高位为0xA1-0xA9,低位为0xA1-0xFE
二、GBK编码
GB2312是中国规定的汉字编码,也可以说是简体中文的字符集编码;而GBK是GB2312的扩展,除了兼容GB2312外,还包括了繁体中文和日文的假名等。
GBK简体字符集的编码同时使用1个字节和2个字节,当高位是0x00~0x7f时,为一个字节,高位为0x80以上时用2个字节表示。当发现一个字节的内容大于0x7f时,那它肯定是个汉字(跟另一个字节拼凑成一个汉字),0x7f(01111111)接下来的数就是0x80(10000000),所以想要大于0x7f,这个字节的最高位都肯定是1,我们之需要判断这个最高位是否为1就行了。例如:a的ASCII码是97(01100001),A的ASCII码是65(01000001).
三、Unicode编码
Unicode是由国际组织设计的一种字符编码方法,可以容纳全世界所有语言文字的编码方案。Unicode的学名叫”UniversalMultipleOctetCoded Character Set“,简称为UCS。Unicode规定了如何编码,但是没有规定如何传输、保存这个编码。例如”汉“字的UCS编码是6C49,我们可以用4个ASCII数字来传输、保存这个编码;也可以使用utf-8编码,3个连续的字节E6B189来表示他。关键在于通信双方都要认可。UTF-8、UTF-7、UTF-16都是被广泛接受的方案。UTF-8的一个特别好友是它与ISO-8859-1完全兼容。UTF是”UCSTransformation
Format“的缩写。
UTF-8是Unicode的一种实现方式,也就是它的字节结构有特殊要求,所以我们说一个汉字的范围是0X4E00到0x9FA5,是指unicode值,至于放在utf-8的编码里去就是由三个字节来组织,所以可以看出unicode是给出一个字符的范围,定义了这个字是码值是多少,至于具体的实现方式可以有多种多样来实现。对于某一个字符的UTF-8编码,如果只有一个字节则其最高二进制位为0;如果是多字节,其第一个字节从最高位开始,连续的二进制位值为1的个数决定了其编码的位数,其余各字节均以10开头。UTF-8最多可用到6个字节。
汉字的unicode范围是:0x4E00~0x9FA5,UTF-8有点类似于Haffman编码,是一种变长的编码方式,尽可能的缩短编码后的字节数大小,它将Unicode编码为:
0x00-0x7F的字符,用单个字节来表示;
0x80-0x7FF的字符用两个字节表示;
0x800-0xFFFF的字符用3字节表示;
一直持续到6个字节,依次类推。
Unicode符号范围 | UTF-8编码方式
(十六进制) | (二进制)
--------------------+---------------------------------------------
0000 0000-0000 007F | 0xxxxxxx
0000 0080-0000 07FF | 110xxxxx10xxxxxx
0000 0800-0000 FFFF | 1110xxxx10xxxxxx 10xxxxxx
0001 0000-0010 FFFF | 11110xxx10xxxxxx 10xxxxxx 10xxxxxx
如:“严”的unicode编码是4E25(100111000100101),根据上表,可以发现4E25处在第三行的范围内(00000800-0000 FFFF),因此“严”的UTF-8编码需要三个字节,即格式是“1110xxxx 10xxxxxx 10xxxxxx”。然后,从“严”的最后一个二进制位开始,依次从后向前填入格式中的x,多出的位补0。这样就得到了,“严”的UTF-8编码是“1110010010111000 10100101”,转换成十六进制就是E4B8A5。
所以当我们需要在GB2312、GBK等和UTF-8之间转换时,必须依赖Unicode码才能实现。
GB2312、GBK-----Unicode-----UTF-8
UTF-8-------Unicode-----GB2312、GBK
参考资料:
(1)汉字Unicode大全:http://mall.webcrow.jp/