Unicode是一種用於一致編碼書面文字的行業標準。學習它的基礎和最重要的部分, 特別是關於UTF-8。

Unicode是一種用於一致編碼書寫文本的行業標準

電腦使用許多 字元集(character sets), 但Unicode是第一個旨在支持地球上(甚至更多地方)每種書面語言的字符集。

它的目標是為每種語言的每個字符提供一個唯一的編號, 並且能夠在任何平台上使用。

Unicode將每個字符映射到一個特定的編碼, 称为代碼點。代碼點採用U+<hex-code>的形式, 範圍從U+0000U+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字符的結合來表示:

"U+0065U+0301" ➡️ "é"

在這種情況下, U+0301被描述為組合符號, 這是一個應用於前一個字符以形成不同字形的字符。

規範化

有時候, 字符可以使用不同的代碼點組合來表示。

例如重音字符: 字母é可以表示為U+00E9e U+0065以及名為“COMBINING ACUTE ACCENT” U+0301的組合:

U+00E9 ➡️ "é"
U+0065U+0301 ➡️ "é"

規範化過程分析字符串中的這種歧義性, 並生成具有任何字符的規范表示形式的字符串。

如果不規範化, 看起來完全相同的字符串在內部表示上有所不同:

表情符號

表情符號是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+0030U+0039
  • 大寫字母從U+0041U+005A
  • 小寫字母從U+0061U+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那麼受歡迎, 但它也有它的應用場景。