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+0065U+0301
兩個號碼:「e」+「往上疊一撇」
畫在螢幕上一模一樣,電腦卻說這兩串不相等 — 搜尋搜不到、排序排錯。解法叫正規化(NFC/NFD),先統一成同一種寫法再比。
👨👩👧
U+1F468ZWJU+1F469ZWJU+1F467
五個號碼黏成一格。中間那個 ZWJ 是隱形的膠水。
丟一段字進去,拆給你看。
貼任何東西都行 — 中文、藏文、emoji、注音、你自己的名字。
看起來幾個字0人眼算的「一格」
CODE POINTS0Unicode 發了幾個號碼
UTF-8 BYTES0存成檔案佔幾個位元組
三個數字常常不一樣。程式當掉、字串切一半變問號、名字存不進資料庫,多半就是把它們當成同一個。
三個常見的誤會。
- 01
看到 □ 不是 Unicode 缺字。那叫豆腐字。號碼存在、字也存在,只是你電腦裡的字型沒有畫這一格。換一套字型就出來了。
- 02
Unicode 不是 UTF-8。Unicode 是號碼表,UTF-8/UTF-16 是把號碼寫成位元組的方法。同一個字,號碼只有一個,位元組寫法有好幾種。
- 03
字數不等於長度。一家人 emoji 你算一個字,程式可能回答 5、也可能回答 11。問「長度」以前,得先講清楚問的是哪一種。
Unicode 不聰明,也不優雅。
它只是一張全人類談出來的號碼單 — 而且還在加。