utf16与utf8都是unicode的不同表达形式,utf8多用于网络数据传输使用,所以其之间的转换还是很有必要的。本文意在实现json解析时处理unicode到utf8转化问题时验证。
基础知识:
utf8规则
1、如果一个字符时单字符,则utf8用一个字节比表示
2、如果utf8用多个字节表示,字第一个字节的前n位位1,第n+1位位0,其余字节开始都已10开始,剩余的字节位使用unicode对应的有效位(从右到做依次填入)填补。
下表总结了编码规则,字母x表示可用编码的位。
Unicode符号范围 | UTF-8编码方式
(十六进制)| (二进制)
――――――�C+―――――――――――――――
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
以此实现编码互转:
typedef int w_char;
char *unicode2utf8(w_char unicode)
{
printf("wchar %x:\n",unicode);
int utf8size=1;
char *utf8 = NULL;
if(unicode <= 0x7F)
{
utf8size=1;
utf8 = (char *)malloc(utf8size+1);
if(!utf8)
return utf8;
utf8[0] = (char)unicode;
}
else if(unicode >= 0x80 && unicode <= 0x07FF )
{
utf8size=2;
utf8 = (char *)malloc(utf8size+1);
if(!utf8)
return utf8;
utf8[0] = 0xC0 | unicode>>6; //从后向前依次填入数位,因为使用两个字节表示,后一个字节使用了6位
utf8[1] = 0x80 | (unicode & (0xFF>>2)); //提取填充第二个字节所使用的unicode字符的后位
}
else if(unicode >= 0x0800 && unicode <= 0xFFFF )
{
utf8size=3;
utf8 = (char *)malloc(utf8size+1);
if(!utf8)
return utf8;
utf8[0] = 0xE0 | unicode>>12;//提取第一个字符使用的unicode位,后续顺序由右向左处理
utf8[1] = 0x80 | ((unicode >> 6) & (0x00FF>>2)); //提取第二个字节使用的unicode的6位,从右向左依次提取
utf8[2] = 0x80 | (unicode & (0xFF>>2));//填充第三个字节使用unicode的6位
}
return utf8;
}
//utf8字节数是unicode对应的编码其实位置
w_char utf82unicode(char *utf8)
{
if(!utf8 || strlen(utf8) <= 0)
return 0;
w_char wchar;
memset(&wchar,0,sizeof(w_char));
int utf8size = 0;
if((utf8[0] & 0xF0) == 0xE0)
{
utf8size = 3;
if(strlen(utf8) < utf8size || (utf8[1] & 0xC0) != 0x80 || (utf8[2] & 0xC0) != 0x80)
return 0;
wchar = wchar | ((0x000F & utf8[0])<<12);//第一字节占用4位
wchar = wchar | ((0x003F & utf8[1] )<<6);//第二个字节占用6位
wchar = wchar | (0x003F & utf8[2]);//第三个字节占用6位,
}
else if( (utf8[0] & 0xE0) == 0xC0)
{
utf8 = 2;
if(strlen(utf8) < utf8size || (utf8[1] & 0xC0) != 0x80 )
return 0;
wchar = wchar | ((0x001F & utf8[0])<<6);
wchar = wchar | (0x003F & utf8[1]);
}
else if(utf8[0] <= 0x7F)
{
wchar = wchar | (utf8[0] & 0x7F);
}
return wchar;
}
以上,作为学习标记,如果有问题,请多指教