编程实现UTF-8到GBK转码

UTF-8的编码规则如下:

U+ 0000 ~ U+ 007F: 0XXXXXXX
U+ 0080 ~ U+ 07FF: 110XXXXX 10XXXXXX
U+ 0800 ~ U+ FFFF: 1110XXXX 10XXXXXX 10XXXXXX

U+10000 ~ U+1FFFF: 11110XXX 10XXXXXX 10XXXXXX 10XXXXXX

GBK字符的UTF-8编码是三个字节。

其十六进制示例如下 :e8 82 a1,对应的UNICODE为: a1 80,对应的GBK编码为 b9 c9

现在将UTF-8编码用二进制表示为:1110,1000 1000,0010 1010,0001,去掉每个字节的字头后为两个字节,表示如下:

1000,0000 1010,0001 表示成十六进制为 0x80 0xa1,与高头的UNICODE编码是相同的,只是字节顺序不一样。

通过查表就可以得到 0xc9b9 = cp936[0x80a1]

编码表 cp936[] 可以从 libiconv的源代码中找到。

整个函数如下:

int utf8_to_gbk(unsigned char *utf8buf, int bufsiz)
{
	unsigned char *pos, *iconvpos, *ptop;
	iconvpos = pos = utf8buf;
	ptop = pos + bufsiz;
	while (pos < ptop) {
		unsigned char ch = *pos;
		if (0xe0 == (ch & 0xf0)) {
			WORD u16val = ((ch & 0xf) << 12) | ((pos[1] & 0x3f) << 6) | (pos[2] & 0x3f);
			*(WORD UNALIGNED *)iconvpos = _byteswap_ushort(cp936[u16val]);
			iconvpos += 2;
			pos += 3;
		}
		else if (iconvpos != pos++) {
			*iconvpos++ = ch;
		}
	}
	return (iconvpos - utf8buf);
}

自己实现的好处是省略了分配新的数组的麻烦。因为UTF-8编码比GBK编码要长,直接在同一个数组内转换就可以了。
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值