前言
在这里只是讲述utf-8是如何转成gbk的大致原理,不贴代码。因为网上有大把的代码实现utf-8与gbk的互转。
在项目中处理字符编码是一件非常痛苦的事情。
测试人员:喂,你的程序有bug。
我:什么bug?
测试人员:在我电脑上中文显示乱码。
我:不可能,我电脑上都没问题,你的电脑是不是有毒。
玩笑开完,说正事。
首先要说明的是,这两种编码是不能直接互相转换的。所以,只能借助第三者-UCS来实现。
UCS:Universal Character Set,俗称Unicode;是所有其他字符集标准的一个超集。就问你们怕不怕。
为什么说要借助Unicode来实现,因为Unicode就是为了一统编码天下来而诞生的。它使用两个字节表示一个字符,即可以表示2^16个字符。基本上可以囊括全世界的字符。因此,世界各国的字符均可以在UCS中找到对应的编码。
互转方法
utf-8---Unicode---gbk
gbk---Unicode---utf-8
以“我是谁”为例
GBK: CED2 CAC7 CBAD
转UNICODE后为: 6211 662F 8C01
再由UNICODE转UTF-8: E68891 E698AF E8B081
知识普及:
utf-8编码:utf英文全程UCS Transfer Format,utf-8表示每次传输8个比特。所以,可以将utf-8理解为Unicode的一个载体。
Unicode与utf-8对应关系
Unicode编码 | utf-8编码 |
---|---|
0000 0000-0000 007F | 0xxxxxxx |
0000 0080-0000 07FF | 110xxxxx 10xxxxxx |
0000 0800-0000 FFFF | 1110xxxx 10xxxxxx 10xxxxxx |
0001 0000-0010 FFFF | 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx |
由上表可以看出,utf-8为变长编码。
gbk编码为天朝独有,其又分为:gb2312,gbk标准,gb18130。
gb2312:又称GB2312-1980。对ASCII的中文扩展;特点是两个字节表示一个字符,且高低字节的前127号均预留给ASCII。共收录汉字6763个。
gbk标准:在GB2312的基础上,去掉低字节中为ASCII预留的前127号。共收录21886个汉字(包括繁体)和符号。
gb18130:采用utf-8类似的编码方式,是1/2/4字节变长编码。兼容gb2312和gbk。共收录汉字70244个。
总结
正是由于每一种编码都能映射到Unicode编码;所以借助与Unicode,可以实现任意两种编码方式之间互相转换。
想要了解更多关于字符编码历史渊源,可以阅读UNICODE,GBK,UTF-8区别这篇文章。里面对于各种编码,讲的蛮详细,还有举例。
扩展
在C++中如何实现两种编码的互转呢?其实很简单。
可以简单粗暴的将Unicode编码对应到WideChar,将其他编码方式(gbk/utf-8等等)对应到MultiChar。
而WideChar对应的数据类型是wchar_t,MultiChar对应的数据类型是char。
windows提供了两个api实现char和whar_t之间的互转,如下:
-
MultiByteToWideChar
:字符串转宽字符 -
WideCharToMultiByte
:宽字符转字符串
gbk转utf-8为例
- gbk转Unicode:将gbk编码的字符串通过
MultiByteToWideChar
接口转换成Unicode编码的数据。- Unicode转utf-8:将Unicode编码的数据通过
WideCharToMultiByte
接口转换成utf-8编码的字符串。
看,是不是很简单。
注意
在调用上述两个接口时,代码页(CodePage)参数要慎用CP_ACP
。想了解更多,请浏览windows开发-CP_ACP采坑这篇文章。
网友评论