GBK,UTF-8字符串转换

时间:2023-01-11 13:19:23

 

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使用一至四个字节为每个字符编码:

  1. 128个US-ASCII字符只需一个字节编码(Unicode范围由U+0000至U+007F)。
  2. 带有附加符号拉丁文希腊文西里尔字母亚美尼亚语希伯来文阿拉伯文叙利亚文它拿字母则需要二个字节编码(Unicode范围由U+0080至U+07FF)。
  3. 其他基本多文种平面(BMP)中的字符(这包含了大部分常用字)使用三个字节编码。
  4. 其他极少使用的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 ~ 
0000 007F

0~7

0XXX XXXX

1

​ASCII码

0000 0080 ~ 
0000 07FF

8~11

110X XXXX 
10XX XXXX

2

0080~​07FF

0000 0800 ~ 
0000 FFFF

12~16

1110 XXXX 
10XX XXXX 
10XX XXXX

3

基本定义范围:0~FFFF

0001 0000 ~ 
001F FFFF

17~21

1111 0XXX 
10XX XXXX 
10XX XXXX 
10XX XXXX

4

Unicode6.1定义范围:0~10 FFFF

0020 0000 ~ 
03FF FFFF

22~26

1111 10XX 
10XX XXXX 
10XX XXXX 
10XX XXXX 
10XX XXXX

5

0400 0000 ~ 
7FFF FFFF

27~31

1111 110
10XX XXXX 
10XX XXXX 
10XX XXXX 
10XX XXXX 
10XX XXXX

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

  1. 根据范围,判定需要多少字节
  2. 从2进制数据从低位往高位填充。

UTF-8和GBK编码的区分

         通过上面的分析,可以知道如果是纯汉字的UTF-8和GBK编码的话,前者的字节数一定是3的倍数,后者则是2的倍数。一个简单的办法就是数字节数。J

         当然如果字节数是6的倍数的话,上面的方法就不好用了。这个时候可以这样区分是GBK还是UTF-8编码:

        

GBK,UTF-8字符串转换