歷史上存在兩個獨立的嘗試創立單一字符集的組織,即國際標準化組織(ISO)和多語言軟件製造商組成的統一碼聯盟。前者開發的 ISO/IEC 10646 項目,後者開發的統一碼項目。因此最初制定了不同的標準。
1991年前後,兩個項目的參與者都認識到,世界不需要兩個不兼容的字符集。於是,它們開始合併雙方的工作成果,併爲創立一個單一編碼表而協同工作。從Unicode 2.0開始,Unicode採用了與ISO 10646-1相同的字庫和字碼;ISO也承諾,ISO 10646將不會替超出U+10FFFF的UCS-4編碼賦值,以使得兩者保持一致。兩個項目仍都存在,並獨立地公佈各自的標準。但統一碼聯盟和ISO/IEC JTC1/SC2都同意保持兩者標準的碼錶兼容,並緊密地共同調整任何未來的擴展。例如UTF-16是ucs-2的父集,UTF-16第一輔助面表示就是ucs-2。UTF-32和ucs-4更是相差無幾。
一:Unicode編碼
Unicode計劃使用了17個平面,一共有17*65536=1114112個碼位。如下:
平面 |
始末字符值 |
中文名稱 |
英文名稱 |
0號平面 |
U+0000 - U+FFFF |
基本多文種平面 |
Basic Multilingual Plane, 簡稱 BMP |
1號平面 |
U+10000 - U+1FFFF |
多文種補充平面 |
Supplementary Multilingual Plane, 簡稱 SMP |
2號平面 |
U+20000 - U+2FFFF |
表意文字補充平面 |
Supplementary Ideographic Plane, 簡稱 SIP |
3號平面 |
U+30000 - U+3FFFF |
表意文字第三平面(未正式使用[1]) |
Tertiary Ideographic Plane, 簡稱 TIP |
4號平面 |
U+40000 - U+DFFFF |
(尚未使用) |
|
14號平面 |
U+E0000 - U+EFFFF |
特別用途補充平面 |
Supplementary Special-purpose Plane, 簡稱 SSP |
15號平面 |
U+F0000 - U+FFFFF |
保留作爲私人使用區(A區)[2] |
Private Use Area-A, 簡稱 PUA-A |
16號平面 |
U+100000 - U+10FFFF |
保留作爲私人使用區(B區)[2] |
Private Use Area-B, 簡稱 PUA-B |
在Unicode 5.0.0版本中,已定義的碼位只有238605個,分佈在平面0、平面1、平面2、平面14、平面15、平面16。其中平面15和平面16上只是定義了兩個各佔65534個碼位的專用區(Private Use Area),分別是0xF0000-0xFFFFD和0x100000-0x10FFFD。所謂專用區,就是保留給大家放自定義字符的區域,可以簡寫爲PUA。平面0也有一個專用區:0xE000-0xF8FF,有6400個碼位。平面0的0xD800-0xDFFF,共2048個碼位,是一個被稱作代理區(Surrogate)的特殊區域(這個代理區的目的用兩個UTF-16字符表示BMP以外的字符。在介紹UTF-16編碼時會介紹)。
unicode的集中編碼方式:UTF-8,UTF-16,UTF-32,UTF-8是變長的。UTF-16是2或四個字節,UTF-32是4個字節。16和32無法和asc碼對應。此外Unicode的實現方式還包括UTF-7、Punycode、CESU-8、SCSU、UTF-32、GB18030等。在非Unicode環境下,由於不同國家和地區採用的字符集不一致,很可能出現無法正常顯示所有字符的情況。微軟公司使用了代碼頁(Codepage)轉換表的技術來過渡性的部分解決這一問題,即通過指定的轉換表將非Unicode的字符編碼轉換爲同一字符對應的系統內部使用的Unicode編碼。可以在“語言與區域設置”中選擇一個代碼頁作爲非Unicode編碼所採用的默認編碼方式,如936爲簡體中文GBK,950爲正體中文Big5(皆指PC上使用的)。在這種情況下,一些非英語的歐洲語言編寫的軟件和文檔很可能出現亂碼。而將代碼頁設置爲相應語言中文處理又會出現問題,這一情況無法避免。從根本上說,完全採用統一編碼纔是解決之道,但目前尚無法做到這一點。代碼頁技術現在廣泛爲各種平臺所採用。UTF-7的代碼頁是65000,UTF-8的代碼頁是65001。
1.UTF-8
UTF-8以字節爲單位對Unicode進行編碼。從Unicode到UTF-8的編碼方式如下:
Unicode編碼(16進制) |
UTF-8 字節流(二進制) |
000000 - 00007F |
0xxxxxxx |
000080 - 0007FF |
110xxxxx 10xxxxxx |
000800 - 00FFFF |
1110xxxx 10xxxxxx 10xxxxxx |
010000 - 10FFFF |
11110xxx 10xxxxxx 10xxxxxx 10xxxxxx |
UTF-8的特點是對不同範圍的字符使用不同長度的編碼。對於0x00-0x7F之間的字符,UTF-8編碼與ASCII編碼完全相同。UTF-8編碼的最大長度是4個字節。從上表可以看出,4字節模板有21個x,即可以容納21位二進制數字。Unicode的最大碼位0x10FFFF也只有21位。
2.UTF-16
UTF-16可以被實現爲UTF-16LE或UTF-16BE
第一個Unicode平面(碼位從U+0000至U+FFFF)包含了最常用的字符。該平面被稱爲基本多語言平面,縮寫爲BMP. UTF-16與UCS-2編碼這個範圍內的碼位爲單個16比特長的碼元,數值等價於對應的碼位. BMP中的這些碼位是僅有的碼位可以在UCS-2被表示.編碼數值和unicode相同。
輔助平面UTF-16要用四個字節表示,基本多語言平面內,從U+D800到U+DFFF之間的碼位區段是永久保留不映射到字符,因此UTF-16利用保留下來的0xD800-0xDFFF區段的碼位來對輔助平面的字符的碼位進行編碼。編碼如下
DC00 |
DC01 |
… |
DFFF |
|
D800 |
10000 |
10001 |
… |
103FF |
D801 |
10400 |
10401 |
… |
107FF |
⋮ |
⋮ |
⋮ |
⋱ |
⋮ |
DBFF |
10FC00 |
10FC01 |
… |
10FFFF |
3.UTF-32
UTF-32可以被實現爲UTF-32LE或UTF-32BE。四個字節比較簡單,編碼值直接與unicode對應。
4.示例:
Unicode編碼 |
UTF-16LE |
UTF-16BE |
UTF32-LE |
UTF32-BE |
0x006C49 |
49 6C |
6C 49 |
49 6C 00 00 |
00 00 6C 49 |
0x020C30 |
43 D8 30 DC |
D8 43 DC 30 |
30 0C 02 00 |
00 02 0C 30 |
例如,“漢字”對應的數字是0x6c49和0x5b57,而編碼的程序數據是:
BYTE data_utf8[] = {0xE6, 0xB1, 0x89,0xE5, 0xAD, 0x97}; // UTF-8編碼
WORD data_utf16[] = {0x6c49, 0x5b57}; //UTF-16編碼
DWORD data_utf32[] = {0x6c49, 0x5b57}; //UTF-32編碼
windows下c&c++編譯器默認是使用gb2312編碼的。如讀取文件或定義字符串默認是gb2312,ide的顯示也是默認識別gb2312。但定義wchar_t時候默認是unicode編碼的,ide環境也是能識別並顯示unicode編碼的。.linux下c&c++編譯器默認是使用utf-8編碼的。如讀取文件或定義字符串默認是utf-8,(沒有使用ide時候,顯示終端有可能只支持utf-8故讀取的其他格式不能正確顯示)。同樣定義wchar_t時候默認是unicode編碼的,(沒有使用ide環境時候,尚不知道能不能識別並顯示unicode編碼)。
注:vs選擇多字節字符集(ansi)和unicode字符集,表示編譯的結果用什麼格式存放,便於移植。UTF-8的特點是對不同範圍的字符使用不同長度的編碼。對於0x00-0x7F之間的字符,UTF-8編碼與ASCII編碼完全相同。UTF-8編碼的最大長度是4個字節。從上表可以看出,4字節模板有21個x,即可以容納21位二進制數字。Unicode的最大碼位0x10FFFF也只有21位。