GB2312和Utf-8编码的转换[1]

关于GB2312Utf-8编码的转换,网上相关的文章似乎很多,不过真正可以拿过来就能用的,并不太多。在WindowsLinux系统中,都有编 码直接转换的函数可以调用,不过在嵌入式系统中,就必须自己加载编码的转换表,来进行编码之间的相互转换了。本文给出相关的转换码表和转换函数,供需要者 参考。


基础知识速览

GB2312
简介

GB2312
GB2312-80是一个简体中文字符集的中国国家标准,全称为《信息交换用汉字编码字符集·基本集》,又称为GB0,由中国国家标准总局 发布,198151日实施。GB2312编码通行于中国大陆;新加坡等地也采用此编码。中国大陆几乎所有的中文系统和国际化的软件都支持 GB2312

GB2312
标准共收录6763个汉字,其中一级汉字3755个,二级汉字3008个;同时,GB 2312收录了包括拉丁字母、希腊字母、日文平假名及片假名字母、俄语西里尔字母在内的682个全角字符。

GB2312
的出现,基本满足了汉字的计算机处理需要,它所收录的汉字已经覆盖中国大陆99.75%的使用频率。
对于人名、古汉语等方面出现的罕用字,GB 2312不能处理,这导致了后来GBKGB 18030汉字字符集的出现。

GB2312
分区存储

B 2312中对所收汉字进行了分区处理,每区含有94个汉字/符号。这种表示方式也称为区位码。
    * 01-09
区为特殊符号。
    * 16-55
区为一级汉字,按拼音排序。
    * 56-87
区为二级汉字,按部首/笔画排序。
10-15
区及88-94区则未有编码。
举例来说,字是GB2312之中的第一个汉字,它的区位码就是1601

GB2312
字节结构

在使用GB2312的程序中,通常采用EUC储存方法,以便兼容于ASCII。浏览器编码表上的“GB2312”,通常都是指“EUC-CN”表示法。

每个汉字及符号以两个字节来表示。第一个字节称为高位字节,第二个字节称为低位字节

高位字节使用了0xA1-0xF7(把01-87区的区号加上0xA0),低位字节使用了0xA1-0xFE(把01-94加上 0xA0)。由于一级汉字从16区起始,汉字区的高位字节的范围是0xB0-0xF7低位字节的范围是0xA1-0xFE,占用的码位是 72*94=6768。其中有5个空位是D7FA-D7FE

例如字在大多数程序中,会以两个字节,0xB0(第一个字节)0xA1(第二个字节)储存。(与区位码对比:0xB0=0xA0+16,0xA1=0xA0+1)。

UNICODE
简介

Unicode(统一码、万国码、单一码、标准万国码)在计算机科学领域,是业界的一种标准,它可以使电脑得以呈现世界上数十种文字的系 统。Unicode 是基于通用字符集(Universal Character Set)的标准来发展,并且同时也以书本的形式(The Unicode Standard,目前第五版由Addison-Wesley Professional出版,ISBN-10: 0321480910)对外发表。Unicode包含了超过十万个字符(在2005年,Unicode的第十万个字符被采纳且认可成为标准之一)、一组可 用以作为视觉参考的代码图表、一套编码方法与一组标准字符编码、一套包含了上标字、下标字等字符特性的列举等。

UNICODE
编码方式

Unicode
的编码方式与 ISO 10646 的通用字符集(Universal Character SetUCS)概念相对应,目前实际应用的 Unicode 版本对应于 UCS-2,使用16位的编码空间。也就是每个字符占用2个字节。这样理论上一共最多可以表示 216 65536 个字符。基本满足各种语言的使用。实际上目前版本的 Unicode 尚未填充满这16位编码,保留了大量空间作为特殊使用或将来扩展。

上述16 Unicode 字符构成基本多文种平面(Basic Multilingual Plane,简称 BMP)。最新(但未实际广泛使用)的 Unicode 版本定义了16个辅助平面,两者合起来至少需要占据21位的编码空间,比3字节略少。但事实上辅助平面字符仍然占用4字节编码空间,与 UCS-4 保持一致。未来版本会扩充到 ISO 10646-1 实现级别3,即涵盖 UCS-4 的所有字符。UCS-4 是一个更大的尚未填充完全的31位字符集,加上恒为0的首位,共需占据32位,即4字节。理论上最多能表示 231 个字符,完全可以涵盖一切语言所用的符号。

BMP
字符的 Unicode 编码表示为 U+hhhh,其中每个 h 代表一个十六进制数位。与 UCS-2 编码完全相同。对应的4字节 UCS-4 编码后两个字节一致,前两个字节的所有位均为0

UTF-8
简介

UTF-8
UNICODE编码的一种实现方式,它有以下特性:

    * UCS
字符 U+0000 U+007F (ASCII) 被编码为字节 0x00 0x7F (ASCII 兼容). 这意味着只包含 7 ASCII 字符的文件在 ASCII UTF-8 两种编码方式下是一样的.
    *
所有 >U+007F UCS 字符被编码为一个多个字节的串, 每个字节都有标记位集. 因此, ASCII 字节 (0x00-0x7F) 不可能作为任何其他字符的一部分.
    *
表示非 ASCII 字符的多字节串的第一个字节总是在 0xC0 0xFD 的范围里, 并指出这个字符包含多少个字节. 多字节串的其余字节都在 0x80 0xBF 范围里. 这使得重新同步非常容易, 并使编码无国界, 且很少受丢失字节的影响.
    *
可以编入所有可能的 231 UCS 代码
    * UTF-8
编码字符理论上可以最多到 6 个字节长, 然而 16 BMP 字符最多只用到 3 字节长.
    * Bigendian UCS-4
字节串的排列顺序是预定的.
    *
字节 0xFE 0xFF UTF-8 编码中从未用到.

下列字节串用来表示一个字符. 用到哪个串取决于该字符在 Unicode 中的序号.
U-00000000 - U-0000007F:     0xxxxxxx
U-00000080 - U-000007FF:     110xxxxx 10xxxxxx
U-00000800 - U-0000FFFF:     1110xxxx 10xxxxxx 10xxxxxx
U-00010000 - U-001FFFFF:     11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
U-00200000 - U-03FFFFFF:     111110xx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx
U-04000000 - U-7FFFFFFF:     1111110x 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx

xxx
的位置由字符编码数的二进制表示的位填入. 越靠右的 x 具有越少的特殊意义. 只用最短的那个足够表达一个字符编码数的多字节串. 注意在多字节串中, 第一个字节的开头"1"的数目就是整个串中字节的数目.

例如: Unicode 字符 U+00A9 = 1010 1001 (版权符号) UTF-8 里的编码为:
    11000010 10101001 = 0xC2 0xA9

而字符 U+2260 = 0010 0010 0110 0000 (不等于) 编码为:
    11100010 10001001 10100000 = 0xE2 0x89 0xA0

这种编码的官方名字拼写为 UTF-8, 其中 UTF 代表 UCS Transformation Format. 请勿在任何文档中用其他名字 (比如 utf8 UTF_8) 来表示 UTF-8, 当然除非你指的是一个变量名而不是这种编码本身.


Windows环境下编码的转换

Windows环境下,对GB2312UTF-8编码的转换,用到如下WinAPI函数:

int WideCharToMultiByte(
    UINT CodePage, // code page
    DWORD dwFlags, // performance and mapping flags
    LPCWSTR lpWideCharStr, // wide-character string
    int cchWideChar, // number of chars in string
    LPSTR lpMultiByteStr, // buffer for new string
    int cbMultiByte, // size of buffer
    LPCSTR lpDefaultChar, // default for unmappable chars
    LPBOOL lpUsedDefaultChar // set when default char used
);

int MultiByteToWideChar(
    UINT CodePage, // code page
    DWORD dwFlags, // character-type options
    LPCSTR lpMultiByteStr, // string to map
    int cbMultiByte, // number of bytes in string
    LPWSTR lpWideCharStr, // wide-character buffer
    int cchWideChar // size of buffer
);    
 

具体转换比较简单,这里不再冗述。


Linux环境下编码的转换

Linux环境下,GB2312UTF-8编码的转换,可以直接用Linux下的iconv命令来处理。

iconv
命令格式如下:

iconv -f org_coding -t dest_method org_file > new_file

linux C库中,也有iconv函数可供程序调用。具体实现比较简单,这里也不冗述。


嵌入式系统的字符编码转换

在嵌入式系统中,由于资源紧张,通常字符的编码格式比较单一。如果需要对多种字符编码进行相关的转换,那么就需要自己的实际需要,来定制字库和相应的转换 码表。下面例程中,中文字库大小为字符集为GB2312的范围,转换程序中,对UTF-8,也只考虑了1byte3bytes的情况。这对于大部分 应用来将,已经足够了。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值