由我来抛砖引玉写第一篇吧。。。
前些日子在开发iphone程序时,由于调用的数据库sqlite是用UTF-8进行的编码,而iOS中字符串显示(特别是中文字符串)使用到的是Unicode编码,所以我们在显示的时候要进行一些转换。那么UTF-8 和 Unicode之间是怎样的变化关系呢?
在这里,我们就不详细介绍Unicode 和 UTF-8 编码了,详细的可以去下面的wikipedia中去了解。
Unicode:http://en.wikipedia.org/wiki/Unicode
UTF-8:http://en.wikipedia.org/wiki/UTF-8
从根本上来说,Unicode和UTF-8的区别就是,Unicode是定长的占两个字节;而UTF-8是一种可变长的编码,对于ASCII码,它采用一个字节,而对于汉字则是两个字节。
UTF-8 和 Unicode 的对应规则如下表所示:
Unicode | UTF-8 |
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-00400000 - U-7FFFFFFF | 1111110x 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx |
汉字以及英文的ASCII编码都在上面红色的范围内。我们以“你”这个字为例,“你”的Unicode编码是0x4F60,转换为二进制为"01001111 01100000", 在上表中的第三行,所以我们对应的把二进制填充进去得到UTF-8编码,二进制为"11100100 10111101 10100000"。
同样的我们可以从UTF-8,按上表规则轻松的转换为Unicode编码。
但是因为UTF-8是变长的,所以要根据UTF-8编码的第一位的前缀来判断该UTF-8编码占用几个字节。就像刚才那个例子中一样,如果我们知道“你”的UTF-8编码,我们根据它的UTF-8编码的第一位,可以判断出来它的UTF-8编码占用3个字节,所以我们需要继续读取2个字节,这才是“你”这个字的完整UTF-8编码。同样的,如果是一个单字节的ASCII码,我们根据其前缀进行判断,就只需要读取一个字节。
下面给出我写的将字符串(主要是中文字符串或夹杂有数字或英文的中文字符串)从UTF-8编码转换为Unicode的程序,供参考。
#define MAX_LEN 1024
int getChLength(unsigned char c)
{
if(c<0x7F) {return 1;}
else if((c & 0xE0) == 0xC0)
{
return 2;
}
else if((c & 0xF0) == 0xE0)
{
return 3;
}
}
unsigned short Character_UTF8ToUnicode(char *characterUTF8, int start, int len)
{
unsigned short *us = (unsigned short *)malloc(sizeof(unsigned short));
char *uchar = (char *)us;
switch (len) {
case 1:
uchar[1] = 0;
uchar[0] = characterUTF8[start];
break;
case 2:
uchar[1] = ((characterUTF8[start]>>2) & 0x07);
uchar[0] = ((characterUTF8[start] & 0x03)<<6) + ((characterUTF8[start] & 0x3F));
break;
case 3:
uchar[1] = ((characterUTF8[start] & 0x0F)<<4) + ((characterUTF8[start+1]>>2) & 0x0F);
uchar[0] = ((characterUTF8[start+1] & 0x03)<<6) + (characterUTF8[start+2] & 0x3F);
break;
}
return us[0];
}
unsigned short * String_UTF8ToUnicode(char * textUTF8)
{
unsigned short unicode[MAX_LEN];
unsigned short *result;
int strCount = 0;
int string_len = strlen(textUTF8);
int ch_len, count_len = 0;
do {
ch_len = getChLength(textUTF8[count_len]);
unicode[strCount] = Character_UTF8ToUnicode(textUTF8, count_len, ch_len);
strCount++;
count_len += ch_len;
} while (count_len < string_len);
unicode[strCount] = '/0';
result = unicode;
return result;
}