Unicode

每個字
一個號碼

電腦只會存數字。所以全世界坐下來開了很多年的會,替每一個字各發一個號碼 — 一個字一個,不准重號。

AU+0041拉丁
語U+8A9E漢字
अU+0905天城體
한U+D55C諺文
🐟U+1F41Femoji

號碼寫成 U+ 加十六進位。這就是 Unicode 的全部野心。

沒有共用號碼以前,長這樣。

從前每個地區各發各的號碼:台灣 Big5、大陸 GB、日本 Shift-JIS、歐美 Latin-1。同一串數字,換一張表去讀,就變成別的字。

E4B8AD E69687 E5AD97

檔案裡真正存的,只有這九個數字。

用 UTF-8 的表讀中文字
用 BIG5 的表讀銝剜��摺�

這就是亂碼。檔案沒壞,只是讀的人拿錯了對照表。Unicode 的解法很粗暴:全世界只留一張表。

這張表有多大?

15 萬+已經編號的字符
160+涵蓋的文字系統
111 萬號碼位上限(到 U+10FFFF)

古埃及聖書體、線形文字 B、注音符號、麻將牌 — 通通排進同一張表。空位還很多,每年繼續加。

號碼,不等於檔案裡的位元組。

號碼是概念,存進硬碟還要翻譯成位元組。最通行的翻譯法叫 UTF-8:號碼越大,用的位元組越多。

A411 byte
éC3A92 bytes
語E8AA9E3 bytes
🐟F09F909F4 bytes

英文字母還是 1 個位元組,所以幾十年前的英文檔案不用改就能用 — 這是 UTF-8 打敗其他方案的原因。代價是中文變成 3 個位元組,比 Big5 的 2 個胖。

你看到一個字,電腦不一定同意。

é
U+00E9
一個號碼:「帶撇的 e」
é
U+0065U+0301
兩個號碼:「e」+「往上疊一撇」

畫在螢幕上一模一樣,電腦卻說這兩串不相等 — 搜尋搜不到、排序排錯。解法叫正規化(NFC/NFD),先統一成同一種寫法再比。

👨‍👩‍👧
U+1F468ZWJU+1F469ZWJU+1F467
五個號碼黏成一格。中間那個 ZWJ 是隱形的膠水。

丟一段字進去,拆給你看。

貼任何東西都行 — 中文、藏文、emoji、注音、你自己的名字。

看起來幾個字0人眼算的「一格」
CODE POINTS0Unicode 發了幾個號碼
UTF-8 BYTES0存成檔案佔幾個位元組

三個數字常常不一樣。程式當掉、字串切一半變問號、名字存不進資料庫,多半就是把它們當成同一個。

三個常見的誤會。

Unicode 不聰明,也不優雅。
它只是一張全人類談出來的號碼單 — 而且還在加。