通過這幾天的研究,終於明白了unicode和utf-8之間編碼的區別。unicode是乙個字符集,而utf-8是unicode的其中一種,unicode是定長的都為雙位元組,而utf-8是可變的,對於漢字來說unicode占有的位元組比utf-8占用的位元組少1個位元組。unicode為雙位元組,而utf-8中漢字佔三個位元組。
utf-8編碼字元理論上可以最多到6個位元組長,然而16位bmp(
basic multilingual plane)字元最多只用到3位元組長。下面看一下utf-8編碼表:
u-00000000 - u-0000007f: 0******x
u-00000080 - u-000007ff: 110***xx 10******
u-00000800 - u-0000ffff: 1110***x 10****** 10******
u-00010000 - u-001fffff: 11110*** 10****** 10****** 10******
u-00200000 - u-03ffffff: 111110xx 10****** 10****** 10****** 10******
u-04000000 - u-7fffffff: 1111110x 10****** 10****** 10****** 10****** 10******
*** 的位置由字元編碼數的二進位制表示的位填入, 越靠右的 x 具有越少的特殊意義,只用最短的那個足夠表達乙個字元編碼數的多位元組串。 注意在多位元組串中, 第乙個位元組的開頭"1"的數目就是整個串中位元組的數目。而第一行中以0開頭,是為了相容ascii編碼,為乙個位元組,第二行就為雙位元組字串,第三行為3位元組,如漢字就屬於這種,以此類推。(個人認為:其實我們可以簡單的把前面的1的個數看成位元組數)
為了要將unicode轉換為utf-8,當然要知道他們的區別到底在什麼地方。下面來看一下,在unicode中的編碼是怎樣轉換成utf-8的,在utf-8中,如果乙個字元
的位元組小於0x80(128)則為ascii字元,佔乙個位元組,可以不用轉換,因為utf-8相容ascii編碼。假如在unicode中漢字「你」的編碼為「u4f60」,把它轉換為二進位制為100111101100000,然後按照utf-8的方法進行轉換。可以將unicode二進位制從地位往高位取出二進位制數字,每次取6位,如上述的二進位制就可以分別取出為如下所示的格式,前面按格式填補,不足8位用0填補。
unicode: 100111101100000 4f60
utf-8:
11100100,
10111101,
10100000 e4bda0
從上面就可以很直觀的看出unicode到utf-8之間的轉換,當然知道了utf-8的格式後,就可以進行逆運算,就是按照格式把它在二進位制中的相應位置上取出,然後在轉換就是所得到的unicode字元了(這個運算可以通過「位移」來完成)。
如上述的「你」的轉換,由於其值大於0x800小於0x10000,因此可以判斷為三位元組儲存,則最高位需要向右移「12」位再根據三位元組格式的最高位為11100000(0xe0)求或(|)就可以得到最高位的值了。同理第二位則是右移「6」位,則還剩下最高位和第二位的二進位制值,可以通過與111111(0x3f)求按位於(&)操作,再和11000000(0x80)求或(|)。第三位就不用移位了,只要直接取最後六位(與111111(ox3f)取&),在與11000000(0x80)求或(|)。ok了,轉換成功!在
vc++中的**如下所示(unicode到utf-8的轉換)。 1
const
wchar_t punicode =l
"你";
2char
utf8[3+
1];3memset(utf8,0,
4);4utf8[0
] =0xe0
|(punicode
>>
12);
5utf8[1
] =0x80
|((punicode
>>6)
&0x3f);6
utf8[2
] =0x80
|(punicode
&0x3f);7
utf8[3
] ="/0
";8//
char[4]就是utf-8的字元「你」了。
當然在utf-8到unicode的轉換也是通過移位等來完成的,就是把utf-8那些格式相應的位置的二進位制數給揪出來。在上述例子中「你」為三個位元組,因此要每個位元組進行處理,有高位到低位進行處理。在utf-8中「你」為
11100100,10111101,10100000。從高位起即第乙個位元組11100100就是把其中的"0100"給取出來,這個很簡單只要和11111(0x1f)取與(&),由三位元組可以得知最到位肯定位於12位之前,因為每次取六位。所以還要將得到的結果左移12位,最高位也就這樣完成了0100,000000,000000。而第二位則是要把「111101」給取出來,則只需將第二位元組10111101和111111(0x3f)取與(&)。在將所得到的結果左移6位與最高位元組所得的結果取或(|),第二位就這樣完成了,得到的結果為0100,111101,000000。以此類推最後一位直接與111111(0x3f)取與(&),再與前面所得的結果取或(|)即可得到結果0100,111101,100000。ok,轉換成功!在
vc++中的**如下所示(
utf-8
到unicode
的轉換)。 1
//utf-8格式的字串
2const
char
*utf8 ="
你";3
wchar_t unicode;
4unicode
=(utf8[0]
&0x1f
) <<12;
5unicode
|=(utf8[1]
&0x3f
) <<6;
6unicode
|=(utf8[2]
&0x3f);7
//unicode is ok!
當然在程式設計過程中不可能只轉換乙個字元,這裡需要注意的是字元的長度一定要算清楚,不然會帶來...以上就是我這幾天研究的結果,至於unicode的轉換為gb2312在mfc中windows有自帶的api(widechar
tomultibyte
)可以轉換。這樣也就能夠將utf-8格式轉換為gb2312了,這裡就不再贅述,如果大家有更好的方法希望指教。
Unicode和UTF 8之間的轉換
unicode是乙個字符集,而utf 8是unicode的其中一種,unicode是定長的都為雙位元組,而utf 8是可變的,對於漢字來說unicode占有的位元組比utf 8占用的位元組少1個位元組。unicode為雙位元組,而utf 8中漢字佔三個位元組。utf 8編碼字元理論上可以最多到6個位...
unicode和utf 8之間的轉換
最近在用vc 開發乙個小工具,平時用慣了.net,用起vc 最鬱悶的就是字串處理。當然最最讓人難於琢磨的就是字符集,編碼之間的轉換。通過這幾天的研究,終於明白了unicode和utf 8之間編碼的區別。unicode是乙個字符集,而utf 8是unicode的其中一種,unicode是定長的都為雙位...
Unicode和UTF 8之間的轉換詳解
通過這幾天的研究,終於明白了unicode和utf 8之間編碼的區別。unicode是乙個字符集,而utf 8是unicode的其中一種,unicode是定長的都為雙位元組,而utf 8是可變的,對於漢字來說unicode占有的位元組比utf 8占用的位元組少1個位元組。unicode為雙位元組,而...