utf16与utf8都是unicode的不同表达形式,utf8多用于网络数据传输使用,所以其之间的转换还是很有必要的。本文意在实现json解析时处理unicode到utf8转化问题时验证。

基础知识:

utf8规则

1、如果一个字符时单字符,则utf8用一个字节比表示

2、如果utf8用多个字节表示,字第一个字节的前n位位1,第n+1位位0,其余字节开始都已10开始,剩余的字节位使用unicode对应的有效位(从右到做依次填入)填补。


下表总结了编码规则,字母x表示可用编码的位。

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

以此实现编码互转:


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;

}



以上,作为学习标记,如果有问题,请多指教