GBK与UTF-8的历史
GBK
1993年,Unicode 1.1版本推出,收录*、*、日本及韩国通用字符集的汉字,总共有20,902个。
*订定了等同于Unicode 1.1版本的“GB 13000.1-93”“信息技术通用多八位编码字符集(UCS)第一部分:体系结构与基本多文种平面”。
由于GB 2312-80只收录6763个汉字,有不少汉字,如部分在GB 2312-80推出以后才简化的汉字(如“啰”),部分人名用字(如中国前总理*的“镕”字),*及香港使用的繁体字,日语及朝鲜语汉字等,并未有收录在内。于是厂商微软利用GB 2312-80未使用的编码空间,收录GB 13000.1-93全部字符制定了GBK编码。
根据微软资料,GBK是对GB2312-80的扩展,也就是CP936字码表 (Code Page 936)的扩展(之前CP936和GB 2312-80一模一样),最早实现于Windows 95简体中文版。虽然GBK收录GB 13000.1-93的全部字符,但编码方式并不相同。
GBK自身并非国家标准,只是曾由国家技术监督局标准化司、电子工业部科技与质量监督司公布为“技术规范指导性文件”。原始GB13000一直未被业界采用,后续国家标准GB18030技术上兼容GBK而非GB13000。
UTF-8
UTF-8(8-bit Unicode Transformation Format)是一种针对Unicode的可变长度字符编码(定长码),也是一种前缀码。它可以用来表示Unicode标准中的任何字符,且其编码中的第一个字节仍与ASCII兼容,这使得原来处理ASCII字符的软件无须或只须做少部份修改,即可继续使用。因此,它逐渐成为电子邮件、网页及其他存储或传送文字的应用中,优先采用的编码。
UTF-8使用一至四个字节为每个字符编码:
- 128个US-ASCII字符只需一个字节编码(Unicode范围由U+0000至U+007F)。
- 带有附加符号的拉丁文、希腊文、西里尔字母、亚美尼亚语、希伯来文、阿拉伯文、叙利亚文及它拿字母则需要二个字节编码(Unicode范围由U+0080至U+07FF)。
- 其他基本多文种平面(BMP)中的字符(这包含了大部分常用字)使用三个字节编码。
- 其他极少使用的Unicode 辅助平面的字符使用四字节编码。
对上述提及的第四种字符而言,UTF-8使用四个字节来编码似乎太耗费资源了。但UTF-8对所有常用的字符都可以用三个字节表示,而且它的另一种选择,UTF-16编码,对前述的第四种字符同样需要四个字节来编码,所以要决定UTF-8或UTF-16哪种编码比较有效率,还要视所使用的字符的分布范围而定。不过,如果使用一些传统的压缩系统,比如DEFLATE,则这些不同编码系统间的的差异就变得微不足道了。若顾及传统压缩算法在压缩较短文字上的效果不大,可以考虑使用Unicode标准压缩格式(SCSU)。
互联网工程工作小组(IETF)要求所有互联网协议都必须支持UTF-8编码。[1] 互联网邮件联盟(IMC)建议所有电子邮件软件都支持UTF-8编码。
编码规则
GBK编码规则
GBK分为单字节和双字节编码,单字节编码同ASCII码。GBK把编码空间分为若干区, 区内分多个位。每个位上对应于一个汉字。所以又称为区位码。汉字的编码空间从B0A1开始到FE4F为止(所有xxFF留空)。所有的双字节编码的高位置1,已和单字节编码区分。
具体对应关系表http://blog.csdn.net/oncreate/article/details/1656806
UTF-8编码
如果UNICODE字符由2个字节表示,则编码成UTF-8很可能需要3个字节。而如果UNICODE字符由4个字节表示,则编码成UTF-8可能需要6个字节。用4个或6个字节去编码一个UNICODE字符可能太多了,但很少会遇到那样的UNICODE字符。 UTF-8转换表表示如下:
UNICODE |
bit数 |
UTF-8 |
byte数 |
备注 |
0000 0000 ~ |
0~7 |
0XXX XXXX |
1 |
ASCII码 |
0000 0080 ~ |
8~11 |
110X XXXX |
2 |
0080~07FF |
0000 0800 ~ |
12~16 |
1110 XXXX |
3 |
基本定义范围:0~FFFF |
0001 0000 ~ |
17~21 |
1111 0XXX |
4 |
Unicode6.1定义范围:0~10 FFFF |
0020 0000 ~ |
22~26 |
1111 10XX |
5 |
|
0400 0000 ~ |
27~31 |
1111 110X |
6 |
|
多字符编码的首字符高位置1,高位1的数目为该编码对应的byte数,且连续的1后接0。对于汉字来讲,其编码的区域在0000 0800-0000 FFFF这个区域,也就是需要三个byte才能表示。容易发现,其高位的值从224开始,后续两个字节都是从128开始。
UNICODE和UTF-8的转换
Unicode 16进制 |
Unicode 2进制 |
bit数 |
UTF-8 2进制 |
UTF-8 16进制 |
CA |
1100 1010 |
8 |
1100 0011 1000 1010 |
C3 8A |
F0 3F |
1111 0000 0011 1111 |
16 |
1110 1111 1000 0000 1011 1111 |
EF 80 BF |
- 根据范围,判定需要多少字节
- 从2进制数据从低位往高位填充。
UTF-8和GBK编码的区分
通过上面的分析,可以知道如果是纯汉字的UTF-8和GBK编码的话,前者的字节数一定是3的倍数,后者则是2的倍数。一个简单的办法就是数字节数。J
当然如果字节数是6的倍数的话,上面的方法就不好用了。这个时候可以这样区分是GBK还是UTF-8编码: