unicode和utf 8之間的轉換

2021-06-02 14:35:40 字數 3335 閱讀 2664

最近在用vc++開發乙個小工具,平時用慣了.net,用起vc++最鬱悶的就是字串處理。當然最最讓人難於琢磨的就是字符集,編碼之間的轉換。通過這幾天的研究,終於明白了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的轉換)。

1const

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之間的轉換詳解

通過這幾天的研究,終於明白了unicode和utf 8之間編碼的區別。unicode是乙個字符集,而utf 8是unicode的其中一種,unicode是定長的都為雙位元組,而utf 8是可變的,對於漢字來說unicode占有的位元組比utf 8占用的位元組少1個位元組。unicode為雙位元組,而...

Unicode和UTF 8之間的轉換詳解

通過這幾天的研究,終於明白了unicode和utf 8之間編碼的區別。unicode是乙個字符集,而utf 8是unicode的其中一種,unicode是定長的都為雙位元組,而utf 8是可變的,對於漢字來說unicode占有的位元組比utf 8占用的位元組少1個位元組。unicode為雙位元組,而...