複製鏈接
請複製以下鏈接發送給好友

統一碼

鎖定
統一碼(Unicode),也叫萬國碼、單一碼,由統一碼聯盟開發,是計算機科學領域裏的一項業界標準,包括字符集編碼方案等。
統一碼是為了解決傳統的字符編碼方案的侷限而產生的,它為每種語言中的每個字符設定了統一併且唯一的二進制編碼,以滿足跨語言、跨平台進行文本轉換、處理的要求。
中文名
統一碼
外文名
Unicode
別    名
國際碼
別    名
單一碼
原    理
統一碼數字檢索法
開發者
統一碼聯盟

統一碼發展歷程

1990年開始研發,1994年正式發佈1.0版本,2023年9月12日發佈15.1.0版本 [2] 

統一碼統一碼簡介

如果把各種文字編碼形容為各地的方言,那麼統一碼就是世界各國合作開發的一種語言。
在這種語言環境下,不會再有語言的編碼衝突,在同屏下,可以顯示任何語言的內容,這就是統一碼的最大好處。就是將世界上所有的文字用2個字節統一進行編碼。那樣,像這樣統一編碼,2個字節就已經足夠容納世界上所有語言的大部分文字了。
Universal Multiple-Octet Coded Character Set,簡稱為UCS
現在用的是UCS-2,即2個字節編碼,而UCS-4是為了防止將來2個字節不夠用才開發的。
統一碼是一種在計算機上使用的字符編碼,1990年開始研發,1994年正式公佈。隨着計算機工作能力的增強,統一碼也在面世以來的十多年裏得到普及。
統一碼是基於通用字符集(Universal Character Set)的標準來發展,同時也以出版物的形式(The 統一碼 Standard,第五版由Addison-Wesley Professional出版,ISBN-10: 0321480910)對外發表。
2005年3月31日推出4.1.0版本。
2023年9月12日發佈15.1.0版本 [2] 

統一碼編碼和實現

大概來説,統一碼編碼系統可分為編碼方式和實現方式兩個層次。

統一碼編碼方式

統一碼是國際組織制定的可以容納世界上所有文字和符號的字符編碼方案。統一碼用數字0-0x10FFFF來映射這些字符,最多可以容納1114112個字符,或者説有1114112個碼位。碼位就是可以分配給字符的數字。UTF-8UTF-16UTF-32都是將數字轉換到程序數據的編碼方案。
統一碼字符集可以簡寫為UCS(統一碼Character Set)。早期的統一碼標準有UCS-2、UCS-4的説法。UCS-2用兩個字節編碼,UCS-4用4個字節編碼。
UCS-4根據最高位為0的最高字節分成2^7=128個group。每個group再根據次高字節分為256個平面(plane)。每個平面根據第3個字節分為256行(row),每行有256個碼位(cell)。group 0的平面0被稱作BMP(Basic Multilingual Plane)。將UCS-4的BMP去掉前面的兩個零字節就得到了UCS-2。
每個平面有2^16=65536個碼位。統一碼計劃使用了17個平面,一共有17*65536=1114112個碼位。在統一碼 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編碼時會介紹。
如前所述在統一碼5.0.0版本中,238605-65534*2-6400-2408=99089。餘下的99089個已定義碼位分佈在平面0、平面1、平面2和平面14上,它們對應着統一碼定義的99089個字符,其中包括71226個漢字。平面0、平面1、平面2和平面14上分別定義了52080、3419、43253和337個字符。平面2的43253個字符都是漢字。平面0上定義了27973個漢字。

統一碼實現方式

在統一碼中,漢字“字”對應的數字是23383。在統一碼中,我們有很多方式將數字23383表示成程序中的數據,包括:UTF-8、UTF-16、UTF-32。UTF是“UCS Transformation Format”的縮寫,可以翻譯成統一碼字符集轉換格式,即怎樣將統一碼定義的數字轉換成程序數據。例如,“漢字”對應的數字是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編碼
這裏用BYTE、WORD、DWORD分別表示無符號8位整數,無符號16位整數和無符號32位整數。UTF-8、UTF-16、UTF-32分別以BYTE、WORD、DWORD作為編碼單位。“漢字”的UTF-8編碼需要6個字節。“漢字”的UTF-16編碼需要兩個WORD,大小是4個字節。“漢字”的UTF-32編碼需要兩個DWORD,大小是8個字節。根據字節序的不同,UTF-16可以被實現為UTF-16LE或UTF-16BE,UTF-32可以被實現為UTF-32LE或UTF-32BE。下面介紹UTF-8、UTF-16、UTF-32、字節序BOM
UTF-8
UTF-8以字節為單位對統一碼進行編碼。從統一碼到UTF-8的編碼方式如下:
統一碼編碼(十六進制)║UTF-8字節流(二進制)
F║0xxxxxxxx║110xxxxx 10xxxxxx║1110xxxx 10xxxxxx 10xxx10xxxx║11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
UTF-8編碼格式
字節
格式
實際編碼位
碼點範圍
1字節
0xxxxxxx
7
0 ~ 127
2字節
110xxxxx 10xxxxxx
11
128 ~ 2047
3字節
1110xxxx 10xxxxxx 10xxxxxx
16
2048 ~ 65535
4字節
11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
21
65536 ~ 2097151
UTF-8的特點是對不同範圍的字符使用不同長度的編碼。對於0x00-0x7F之間的字符,UTF-8編碼與ASCII編碼完全相同。UTF-8編碼的最大長度是4個字節。從上表可以看出,4字節模板有21個x,即可以容納21位二進制數字。統一碼的最大碼位0x10FFFF也只有21位。
例1:“漢”字的統一碼編碼是0x6C49。0x6C49在0x0800-0xFFFF之間,使用用3字節模板了:1110xxxx 10xxxxxx 10xxxxxx。將0x6C49寫成二進制是:0110 1100 0100 1001,用這個比特流依次代替模板中的x,得到:1110 0110 1011 0001 1000 1001,即E6 B1 89。
例2:統一碼編碼0x20C30在0x010000-0x10FFFF之間,使用用4字節模板了:11110xxx 10xxxxxx 10xxxxxx 10xxxxxx。將0x20C30寫成21位二進制數字(不足21位就在前面補0):0 0010 0000 1100 0011 0000,用這個比特流依次代替模板中的x,得到:,即F0 A0 B0 B0。
UTF-16
UTF-16編碼以16位無符號整數為單位。我們把統一碼編碼記作U。編碼規則如下:
如果U<0x10000,U的UTF-16編碼就是U對應的16位無符號整數(為書寫簡便,下文將16位無符號整數記作WORD)。
如果U≥0x10000,我們先計算U'=U-0x10000,然後將U'寫成二進制形式:yyyy yyyy yyxx xxxx xxxx,U的UTF-16編碼(二進制)就是:110110yyyyyyyyyy 110111xxxxxxxxxx。
為什麼U'可以被寫成20個二進制位?統一碼的最大碼位是0x10ffff,減去0x10000後,U'的最大值是0xfffff,所以肯定可以用20個二進制位表示。例如:統一碼編碼0x20C30,減去0x10000後,得到0x10C30,寫成二進制是:0001 0000 1100 0011 0000。用前10位依次替代模板中的y,用後10位依次替代模板中的x,就得到:1101 1000 0100 0011 和 1101 1100 0011 0000,即0xD843 0xDC30。
按照上述規則,統一碼編碼0x10000-0x10FFFF的UTF-16編碼有兩個WORD,第一個WORD的高6位是110110,第二個WORD的高6位是110111。可見,第一個WORD的取值範圍(二進制)是到1111111111,即0xD800-0xDBFF。第二個WORD的取值範圍(二進制)是到11011111 11111111,即0xDC00-0xDFFF。
為了將一個WORD的UTF-16編碼與兩個WORD的UTF-16編碼區分開來,統一碼編碼的設計者將0xD800-0xDFFF保留下來,並稱為代理區(Surrogate):
D800-DB7F ║ High Surrogates ║ 高位替代
DB80-DBFF ║ High Private Use Surrogates ║ 高位專用替代
DC00-DFFF ║ Low Surrogates ║ 低位替代
高位替代就是指這個範圍的碼位是兩個WORD的UTF-16編碼的第一個WORD。低位替代就是指這個範圍的碼位是兩個WORD的UTF-16編碼的第二個WORD。那麼,高位專用替代是什麼意思?我們來解答這個問題,順便看看怎麼由UTF-16編碼推導統一碼編碼。
如果一個字符的UTF-16編碼的第一個WORD在0xDB80到0xDBFF之間,那麼它的統一碼編碼在什麼範圍內?我們知道第二個WORD的取值範圍是0xDC00-0xDFFF,所以這個字符的UTF-16編碼範圍應該是0xDB80 0xDC00到0xDBFF 0xDFFF。我們將這個範圍寫成二進制:
110100 - 11
按照編碼的相反步驟,取出高低WORD的後10位,並拼在一起,得到
0 1111 1111 1111 1111
即0xe0000-0xfffff,按照編碼的相反步驟再加上0x10000,得到0xf0000-0x10ffff。這就是UTF-16編碼的第一個WORD在0xdb80到0xdbff之間的統一碼編碼範圍,即平面15和平面16。因為統一碼標準將平面15和平面16都作為專用區,所以0xDB80到0xDBFF之間的保留碼位被稱作高位專用替代。
UTF-32
UTF-32編碼以32位無符號整數為單位。統一碼的UTF-32編碼就是其對應的32位無符號整數。
根據字節序的不同,UTF-16可以被實現為UTF-16LE或UTF-16BE,UTF-32可以被實現為UTF-32LE或UTF-32BE。例如:
統一碼編碼║ 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
判斷字節流的字節序
統一碼標準建議用BOM(Byte Order Mark)來區分字節序,即在傳輸字節流前,先傳輸被作為BOM的字符"零寬無中斷空格"。這個字符的編碼是FEFF,而反過來的FFFE(UTF-16)和FFFE0000(UTF-32)在統一碼中都是未定義的碼位,不應出現在實際傳輸中。下表是各種UTF編碼的BOM:
UTF編碼 ║ Byte Order Mark
UTF-8 ║ EF BB BF
UTF-16LE ║ FF FE
UTF-16BE ║ FE FF
UTF-32LE ║ FF FE 00 00
UTF-32BE ║ 00 00 FE FF
基本上,計算機只是處理數字。它們指定一個數字,來儲存字母或其他字符。在創造統一碼之前,有數百種指定這些數字的編碼系統。沒有一個編碼可以包含足夠的字符:例如,單單歐洲共同體就需要好幾種不同的編碼來包括所有的語言。即使是單一種語言,例如英語,也沒有哪一個編碼可以適用於所有的字母,標點符號,和常用的技術符號。這些編碼系統也會互相沖突。也就是説,兩種編碼可能使用相同的數字代表兩個不同的字符,或使用不同的數字代表相同的字符。任何一台特定的計算機(特別是服務器)都需要支持許多不同的編碼,但是,不論什麼時候數據通過不同的編碼或平台之間,那些數據總會有損壞的危險。

統一碼ASCII碼

大多數計算機採用美國標準信息交換碼(ASCII碼),它是表示所有大小寫字母、數字、標點符號和控制字符的7位編碼方案。統一碼包含ASCII碼,'\u0000'到'\u007F'對應全部128個ACSII字符。在JAVA中可以使用統一碼。

統一碼編碼範圍

注:
3400-4DBF/4E00-9FFF/20000-3FFFF:中日韓越統一表意文字(CJKV Unified Ideographs) [1] 
編碼範圍
0000-007F:C0控制符及基本拉丁文(C0 Control and Basic Latin)
0080-00FF:C1控制符及拉丁文補充-1(C1 Control and Latin 1 Supplement)
0100-017F:拉丁文擴展-A(Latin Extended-A)
0180-024F:拉丁文擴展-B(Latin Extended-B)
0250-02AF:國際音標擴展(IPA Extensions)
02B0-02FF:空白修飾字母(Spacing Modifiers)
0300-036F:結合用讀音符號(Combining Diacritics Marks)
0370-03FF:希臘文科普特文(Greek and Coptic)
0400-04FF:西裏爾字母(Cyrillic)
0500-052F:西裏爾字母補充(Cyrillic Supplement)
0530-058F:亞美尼亞語(Armenian)
0590-05FF:希伯來文(Hebrew)
0600-06FF:阿拉伯文(Arabic)
0700-074F:敍利亞文(Syriac)
0750-077F:阿拉伯文補充(Arabic Supplement)
0780-07BF:馬爾代夫語(Thaana)
07C0-077F:西非書面語言(N'Ko)
0800-085F:阿維斯塔語巴列維語(Avestan and Pahlavi)
0860-087F:曼達安語(Mandaic)
0880-08AF:撒馬利亞語(Samaritan
0900-097F:天城文書(Devanagari
0980-09FF:孟加拉語(Bengali)
0A00-0A7F:古木基文(Gurmukhi)
0A80-0AFF:古吉拉特文(Gujarati)
0B00-0B7F:奧里亞文(Oriya)
0B80-0BFF:泰米爾文(Tamil)
0C00-0C7F:泰盧固文(Telugu)
0C80-0CFF:卡納達文(Kannada)
0D00-0D7F:馬拉雅拉姆語(Malayalam)
D80-0DFF僧伽羅語(Sinhala)
0E00-0E7F:泰文(Thai)
0E80-0EFF:老撾文(Lao)
0F00-0FFF:藏文(Tibetan)
1000-109F:緬甸語(Myanmar)
10A0-10FF:格魯吉亞語(Georgian)
1100-11FF:朝鮮文字母(Hangul Jamo)
1200-137F:埃塞俄比亞語(Ethiopic)
1380-139F:埃塞俄比亞語補充(Ethiopic Supplement)
13A0-13FF:切羅基語(Cherokee)
1400-167F:統一加拿大土著語音節(Unified Canadian Aboriginal Syllabics)
1680-169F:歐甘字母(Ogham)
16A0-16FF:如尼文(Runic)
1700-171F:塔加洛語 (Tagalog)
1720-173F:哈努諾文(Hanunóo)
1740-175F:布錫文(Buhid)
1760-177F:塔格巴努亞文(Tagbanwa)
1780-17FF:高棉語Khmer
1800-18AF蒙古文(Mongolian)
18B0-18FF:韃靼語(Cham)
1900-194F:林布文(Limbu)
1950-197F:德宏傣語(Tai Le)
1980-19DF:新傣仂語(New Tai Lue)
19E0-19FF:高棉語記號(Khmer Symbols)
1A00-1A1F:布吉文(Buginese
1A20-1A5F:巴塔克文(Batak)
1A80-1AEF:蘭納文(Lanna/Tai Tham)
1B00-1B7F:巴釐語(Balinese)
1B80-1BB0:巽他語(Sundanese)
1BC0-1BFF:救世苗文(Pahawh Hmong)
1C00-1C4F:雷布查語(Lepcha)
1C50-1C7F:奧爾其基語字母(Ol Chiki)
1C80-1CDF:曼尼普爾語(Meithei/Manipuri)
1D00-1D7F:語音學擴展(Phonetic Extensions)
1D80-1DBF:語音學擴展補充(Phonetic Extensions Supplement)
1DC0-1DFF:結合用讀音符號補充(Combining Diacritics Marks Supplement)
1E00-1EFF:拉丁文擴充附加(Latin Extended Additional)
1F00-1FFF:希臘語擴充(Greek Extended)
2000-206F:常用標點(General Punctuation)
2070-209F:上標下標(Superscripts and Subscripts)
20A0-20CF:貨幣符號(Currency Symbols)
20D0-20FF:組合用記號(Combining Diacritics Marks for Symbols)
2100-214F:字母式符號(Letterlike Symbols)
2150-218F:數字形式(Number Form)
2190-21FF:箭頭(Arrows)
2200-22FF:數學運算符(Mathematical Operator)
2300-23FF:雜項工業符號(Miscellaneous Technical)
2400-243F:控制圖片(Control Pictures)
2440-245F:光學識別符(Optical Character Recognition)
2460-24FF:封閉式字母數字(Enclosed Alphanumerics)
2500-257F:製表符(Box Drawing)
2580-259F:方塊元素(Block Element)
25A0-25FF:幾何圖形(Geometric Shapes)
2600-26FF:雜項符號(Miscellaneous Symbols)
2700-27BF:印刷符號(Dingbats)
27C0-27EF:雜項數學符號-A(Miscellaneous Mathematical Symbols-A)
27F0-27FF:追加箭頭-A(Supplemental Arrows-A)
2800-28FF:盲文點字模型(Braille Patterns)
2900-297F:追加箭頭-B(Supplemental Arrows-B)
2980-29FF:雜項數學符號-B(Miscellaneous Mathematical Symbols-B)
2A00-2AFF:追加數學運算符(Supplemental Mathematical Operator)
2B00-2BFF:雜項符號和箭頭(Miscellaneous Symbols and Arrows)
2C00-2C5F:格拉哥里字母(Glagolitic)
2C60-2C7F:拉丁文擴展-C(Latin Extended-C)
2C80-2CFF:古埃及語(Coptic)
2D00-2D2F:格魯吉亞語補充(Georgian Supplement)
2D30-2D7F:提非納文(Tifinagh)
2D80-2DDF:埃塞俄比亞語擴展(Ethiopic Extended)
2E00-2E7F:追加標點(Supplemental Punctuation)
2E80-2EFF:CJK部首補充(CJK Radicals Supplement)
2F00-2FDF:康熙字典部首(Kangxi Radicals)
2FF0-2FFF:表意文字描述符(Ideographic Description Characters)
3000-303F:CJK符號和標點(CJK Symbols and Punctuation)
3040-309F:日文平假名(Hiragana)
30A0-30FF:日文片假名Katakana
3100-312F:注音字母Bopomofo
3130-318F:朝鮮文兼容字母(Hangul Compatibility Jamo)
3190-319F:象形字註釋標誌(Kanbun)
31A0-31BF:注音字母擴展(Bopomofo Extended)
31C0-31EF:CJK筆畫(CJK Strokes)
31F0-31FF:日文片假名語音擴展(Katakana Phonetic Extensions)
3200-32FF:封閉式CJK文字和月份(Enclosed CJK Letters and Months)
3300-33FF:CJK兼容(CJK Compatibility)
3400-4DBF:CJK統一表意符號擴展-A(CJK Unified Ideographs Extension-A)
4DC0-4DFF:易經六十四卦符號(Yijing Hexagrams Symbols)
4E00-9FFF:CJK統一表意符號(CJK Unified Ideographs)
A000-A48F:彝文音節(Yi Syllables)
A490-A4CF:彝文字根(Yi Radicals)
A500-A61F:瓦伊語(Vai)
A660-A6FF:統一加拿大土著語音節補充(Unified Canadian Aboriginal Syllabics Supplement)
A700-A71F:聲調修飾字母(Modifier Tone Letters)
A720-A7FF:拉丁文擴展-D(Latin Extended-D)
A800-A82F:錫爾赫特文字母(Syloti Nagri)
A840-A87F:八思巴字(Phags-pa)
A880-A8DF:索拉什特拉語Saurashtra
A900-A97F:爪哇語(Javanese)
A980-A9DF:查克瑪語(Chakma)
AA00-AA3F:Varang Kshiti
AA40-AA6F:索拉索姆字母(Sorang Sompeng)
AA80-AADF:尼瓦爾語(Newari)
AB00-AB5F:越南傣語(Vi?t Thái)
AB80-ABA0:克耶字母(Kayah Li)
AC00-D7AF:朝鮮文音節(Hangul Syllables)
D800-DBFF:High-half zone of UTF-16
DC00-DFFF:Low-half zone of UTF-16
E000-F8FF:自行使用區域(Private Use Zone)
F900-FAFF:CJK兼容象形文字(CJK Compatibility Ideographs)
FB00-FB4F:字母表達形式(Alphabetic Presentation Form)
FB50-FDFF:阿拉伯表達形式A(Arabic Presentation Form-A)
FE00-FE0F:變量選擇符(Variation Selector)
FE10-FE1F:豎排形式(Vertical Forms)
FE20-FE2F:組合用半符號(Combining Half Marks)
FE30-FE4F:CJK兼容形式(CJK Compatibility Forms)
FE50-FE6F:小型變體形式(Small Form Variants)
FE70-FEFF:阿拉伯表達形式B(Arabic Presentation Form-B)
FF00-FFEF:半型及全型形式(Halfwidth and Fullwidth Form)
FFF0-FFFF:特殊(Specials)
10000–1FFFF:第1輔助平面,多文種補充平面(Supplementary Multilingual Plane, SMP) [1] 
20000–2FFFF:第2輔助平面,表意文字補充平面(Supplementary Ideographic Plane, SIP) [1] 
30000–3FFFF:第3輔助平面,表意文字第三平面(Tertiary Ideographic Plane, TIP)
40000–DFFFF:第4-13輔助平面,尚未使用
E0000–EFFFF:第14輔助平面,特別用途補充平面(Supplementary Special-purpose Plane, SSP)
F0000–FFFFF:第15輔助平面,保留作為私人使用區(Private Use Area, PUA
100000–10FFFF:第16輔助平面,保留作為私人使用區(Private Use Area, PUA) [1] 

統一碼統一碼編碼原則

Universality:提供單一、綜合的字符集,編碼一切現代與大部分歷史文獻的字符。
Efficiency:易於處理與分析。
Characters, not glyphs:字符,而不是字形。
Semantics:字符要有良好定義的語義。
Plain text:僅限於文本字符。
Logical order:默認內存表示是其邏輯序。
Unification:把不同語言的同一書寫系統(scripts)中相同字符統一起來。
Dynamic composition:附加符號可以動態組合。
Stability:已分配的字符與語義不再改變。
Convertibility:統一碼與其他著名字符集可以精確轉換。
參考資料