Unicode和UTF-8介紹
Unicode是一種用於一致編碼書面文字的行業標準。學習它的基礎和最重要的部分, 特別是關於UTF-8。
Unicode是一種用於一致編碼書寫文本的行業標準。
電腦使用許多 字元集(character sets), 但Unicode是第一個旨在支持地球上(甚至更多地方)每種書面語言的字符集。
它的目標是為每種語言的每個字符提供一個唯一的編號, 並且能夠在任何平台上使用。
Unicode將每個字符映射到一個特定的編碼, 称为代碼點。代碼點採用U+<hex-code>
的形式, 範圍從U+0000
到U+10FFFF
。
例如, 代碼點類似於U+004F
。它的含義取決於所使用的字符編碼。
Unicode定義了不同的字符編碼, 其中最常用的是UTF-8、UTF-16和UTF-32。
UTF-8絕對是Unicode系列中最受歡迎的字符編碼, 特別是在Web上。例如, 本文就是用UTF-8編寫的。
目前已實現了多達135,000多種不同的字符, 提供了超過1,100,000個空間。
腳本
所有支持的Unicode字符都被分組為腳本。
每種不同的字符集都有一個腳本:
- 拉丁文(包括所有ASCII字符和其他西方字符)
- 韓文
- 古匈牙利文
- 希伯來文
- 希臘文
- 亞美尼亞文
- …等等!
完整列表定義在ISO 15924標準中。
有關腳本的更多信息:點擊這裡
平面
除了腳本, Unicode還通過平面對字符進行組織。
它通過檢查代碼點值來對它們進行分組:
平面 | 範圍 |
---|---|
0 | U+0000 - U+FFFF |
1 | U+10000 - U+1FFFF |
2 | U+20000 - U+2FFFF |
… | … |
14 | U+E0000 - U+EFFFF |
15 | U+F0000 - U+FFFFF |
16 | U+100000 - U+10FFFF |
總共有17個平面。
第一個平面是特殊的, 称為基本多語言平面(BMP), 包含大部分現代字符和符號, 來自拉丁文、西里爾文、希臘文腳本。
另外16個平面被稱為astral平面。值得注意的是, 目前第3到第13個平面是空的。
astral平面中包含的代碼點被稱為astral代碼點。
astral代碼點是高於U+10000
的代碼點。
代碼單元
代碼點在內部以代碼單元形式存儲。代碼單元是字符的位表示法, 其長度根據字符編碼而變。
UTF-32使用32位的代碼單元。
UTF-8使用8位的代碼單元, UTF-16使用16位的代碼單元。如果一個代碼點需要更大的大小, 則將用2個(或多個, 在UTF-8中)代碼單元表示。
字形
字形是表示書寫系統的單位的符號。它基本上是對字符的看法和它應該是什麼樣子。
字跡
字跡是字形的圖形表示:它在屏幕上的可視化顯示, 顯示在屏幕上的實際外觀。
序列
Unicode允許將不同的字符組合在一起形成一個字形。
例如重音字符: 字母é
可以通過使用字母e
U+0065
和名為“COMBINING ACUTE ACCENT” U+0301
的Unicode字符的結合來表示:
1 | "U+0065U+0301" ➡️ "é" |
在這種情況下, U+0301
被描述為組合符號, 這是一個應用於前一個字符以形成不同字形的字符。
規範化
有時候, 字符可以使用不同的代碼點組合來表示。
例如重音字符: 字母é
可以表示為U+00E9
和e
U+0065
以及名為“COMBINING ACUTE ACCENT” U+0301
的組合:
1 | U+00E9 ➡️ "é" |
規範化過程分析字符串中的這種歧義性, 並生成具有任何字符的規范表示形式的字符串。
如果不規範化, 看起來完全相同的字符串在內部表示上有所不同:
表情符號
表情符號是Unicode的astral平面字符, 它們提供了一種在屏幕上擁有圖像而實際上沒有真實圖像的方式, 只使用字體字形。
例如, 🐶 符號編碼為 U+1F436
。
前128個字符
Unicode的前128個字符與ASCII字符集相同。
前32個字符 U+0000
-U+001F
(0-31)稱為控制字符。
它們是過去的產物, 現在大部分已經過時。它們用於電傳機, 這是傳真出現之前存在的東西。
從U+0020
(32)到U+007E
(126), 它們包含數字、字母和一些符號:
Unicode | ASCII code | Glyph |
---|---|---|
U+0020 | 32 | (space) |
U+0021 | 33 | ! |
U+0022 | 34 | ” |
U+0023 | 35 | # |
U+0024 | 36 | $ |
U+0025 | 37 | % |
U+0026 | 38 | & |
U+0027 | 39 | ’ |
U+0028 | 40 | ( |
U+0029 | 41 | ) |
U+002A | 42 | * |
U+002B | 43 | + |
U+002C | 44 | , |
U+002D | 45 | - |
U+002E | 46 | . |
U+002F | 47 | / |
U+0030 | 48 | 0 |
U+0031 | 49 | 1 |
U+0032 | 50 | 2 |
U+0033 | 51 | 3 |
U+0034 | 52 | 4 |
U+0035 | 53 | 5 |
U+0036 | 54 | 6 |
U+0037 | 55 | 7 |
U+0038 | 56 | 8 |
U+0039 | 57 | 9 |
U+003A | 58 | : |
U+003B | 59 | ; |
U+003C | 60 | < |
U+003D | 61 | = |
U+003E | 62 | > |
U+003F | 63 | ? |
U+0040 | 64 | @ |
U+0041 | 65 | A |
U+0042 | 66 | B |
U+0043 | 67 | C |
U+0044 | 68 | D |
U+0045 | 69 | E |
U+0046 | 70 | F |
U+0047 | 71 | G |
U+0048 | 72 | H |
U+0049 | 73 | I |
U+004A | 74 | J |
U+004B | 75 | K |
U+004C | 76 | L |
U+004D | 77 | M |
U+004E | 78 | N |
U+004F | 79 | O |
U+0050 | 80 | P |
U+0051 | 81 | Q |
U+0052 | 82 | R |
U+0053 | 83 | S |
U+0054 | 84 | T |
U+0055 | 85 | U |
U+0056 | 86 | V |
U+0057 | 87 | W |
U+0058 | 88 | X |
U+0059 | 89 | Y |
U+005A | 90 | Z |
U+005B | 91 | [ |
U+005C | 92 | \ |
U+005D | 93 | ] |
U+005E | 94 | ^ |
U+005F | 95 | _ |
U+0060 | 96 | ` |
U+0061 | 97 | a |
U+0062 | 98 | b |
U+0063 | 99 | c |
U+0064 | 100 | d |
U+0065 | 101 | e |
U+0066 | 102 | f |
U+0067 | 103 | g |
U+0068 | 104 | h |
U+0069 | 105 | i |
U+006A | 106 | j |
U+006B | 107 | k |
U+006C | 108 | l |
U+006D | 109 | m |
U+006E | 110 | n |
U+006F | 111 | o |
U+0070 | 112 | p |
U+0071 | 113 | q |
U+0072 | 114 | r |
U+0073 | 115 | s |
U+0074 | 116 | t |
U+0075 | 117 | u |
U+0076 | 118 | v |
U+0077 | 119 | w |
U+0078 | 120 | x |
U+0079 | 121 | y |
U+007A | 122 | z |
U+007B | 123 | { |
U+007C | 124 | | |
U+007D | 125 | } |
U+007E | 126 | ~ |
- 數字從
U+0030
到U+0039
- 大寫字母從
U+0041
到U+005A
- 小寫字母從
U+0061
到U+007A
U+007F(127)是刪除字符。
其餘的就是超出ASCII範圍的, 並且是獨占Unicode的。
你可以在維基百科上找到整個列表:點擊這裡
Unicode編碼
UTF-8
UTF-8是一種變長字符編碼, 它可以使用1到4個8位字節編碼所有Unicode覆蓋的字符。
它最初由Ken Thompson和Rob Pike於1992年設計。對於對任何有興趣的Go程序語言的人來說, 這兩個名字是熟悉的, 因為他們也是該語言的原始創建者之一。
W3C建議在HTML文件中使用UTF-8作為默認編碼, 根據統計數據顯示, 截至2018年4月, 91.3%的網頁使用的是它。
在引入UTF-8時, ASCII是西方世界最流行的字符編碼。在ASCII中, 所有字母、數字和符號都被指定一個ASCII碼, 並且該碼被定為8位, 僅能表示最多255個字符, 正好足夠。
UTF-8設計時考慮了與ASCII的向後兼容性。這對於它的採用非常重要, 因為ASCII更古老(1963年)和廣泛使用, 切換到UTF-8幾乎是透明的。
UTF-8的前128個字符與ASCII完全對應。為什麼是128?因為ASCII使用7位編碼, 允許最多128種組合。為什麼是7位呢?現在我們認為8位是理所當然的, 但在ASCII構思時代, 7位制系統也很流行。
由於100%與ASCII兼容, 使UTF-8也非常高效, 因為在西方語言中最常使用的字符只需使用1個字節編碼。
以下是字節使用情況的映射:
字節數 | 開始 | 結束 |
---|---|---|
1 | U+0000 |
U+007F |
2 | U+0080 |
U+07FF |
3 | U+0800 |
U+FFFF |
4 | U+10000 |
U+10FFFF |
請記住, 在ASCII中, 字母被編碼為數字。如果字母”A”在ASCII中以數字”65”表示, 使用UTF-8, 它編碼為U+0041
。
你問為什麼不是U+0065
?嗯, 因為Unicode使用16進制基數, 代替了10進制, 你有一套16個數字而不是10個數字。
請觀看這個視頻, 它很好地解釋了這種UTF-8和ASCII的兼容性。
UTF-16
UTF-16是另一種非常流行的Unicode編碼。例如, Java在內部表示任何字符時就使用UTF-16。它也是JavaScript在內部使用的2種編碼之一, 另一種是UCS-2。它也被許多其他系統使用, 如Windows。
UTF-16是一種變長編碼系統, 像UTF-8一樣使用2個字節(16位)作為任何字符表示的最小值。因此, 它與ASCII標準不兼容。
基本多語言平面(BMP)中的代碼點使用2個字節進行存儲。在astral平面中的代碼點使用4個字節進行存儲。
UTF-32
UTF-8使用的最小位數是1字節, UTF-16則使用的最小位數是2字節。
UTF-32始終使用4字節, 不進行任何空間使用上的優化, 因此它浪費了大量帶寬。由於檢查的內容較少, 因此操作速度比較快。
它沒有UTF-8和UTF-16那麼受歡迎, 但它也有它的應用場景。