UniHan
這幾天琢磨着怎么方便的給漢字注音, 因為要知道具體哪些Unicode是給漢字用的, 就讀了讀Unicode的官方文檔. 目前unicode已經發展到了7.0. 不看不知道, 發現Unicode的定義中頗有些有趣的內容, 寫下了給大家分享下, 也算是個筆記.
Unicode中跟漢字相關統稱為UniHan, 官方文檔在http://www.unicode.org/reports/tr38/
其中常用的縮寫叫CJK, 就是中日韓的意思, 顯然是把三種基於漢語的文字列在一起.
此文檔內容講了一大堆, 基本意思就是說這三種文字是同源的, 有很多統一的地方, 也有眾多差異. Unicode中的文字並不是自己發明的或直接研究的成果, 而都是對各種現有權威資料的匯總和總結, 比如簡體字主要基於中國的國標, 什么GB12345等. 除了定義每個字的字形和code point外, 還從其他資料中搜集了其他信息, 如拼音, 異體字, 筆畫,簡單的英文翻譯,部首,康熙字典部首...
就拿其中我比較關心的拼音來說, uniHan有一個zip包, 叫UniHan.zip, ftp://www.unicode.org/Public/zipped/7.0.0/unihan.zip
其中文件UniHan_Readings.txt就包含了各種拼音信息. 截圖如下:

U+6F84就是漢字"澄"的code point, 從上面我們可以看到: 一個英語定義 kDefinition,
用廣東話定義的發音kCantonese, kHanyuPinyin是<漢語大字典>中對此字的發音定義; kMandarin描述的是這個字在普通話中最常用的發音(對多音字有意義); 而其他日語韓語的部分我就看不懂了, 懂行的一看便知.
根據文檔TR38記錄, Unicode中的拼音搜集了四種
-
kHanyuPinlu
現代漢語頻率詞典
-
kHanyuPinyin
漢語大字典
-
kMandarin
常用發音
-
kXHC1983
現代漢語詞典
這個只是text格式的, 比較容易分析, 其他鏈接還有xml格式的, 我就不多說了.
文章中提到了X,Y,Z三軸的說法, 大概意思就是說所有的漢字都可以定位在X,Y,Z三個坐標軸上, 這是為了建立各個文字字形與其含義之間的關系. X軸代表含義,Y軸代表某個具體意思的字的各種字形, 而Z軸就是字形的小變形, 舉個例子說: "說" "貓"兩個字有完全不同的意思, 所以在X軸上是兩個不同的值; "貓" 和 "貓"就是一個意思, 所有他們的X軸的值是相同的, 但由於字形有很大差異, 所以Y的值是不一樣的; 而 "說"和"説"兩個字X軸Y軸都是一樣的, 但由於其寫法的小差異,他們的Z值是不同的.
下面說說unihan 中字符的code point分布.
簡單的說, 跟中文有關的有兩個大部分, 一部分是各種漢字和日韓文字;另一部分是輔助的東西, 如偏旁部首, 全字符的英文, 全字符的標點符號,諸如此類.
先說基本的部分:漢字
漢字中最大的一部分叫CJK Unified Ideographs(中日韓統一表意符號集) U+4E00 – 9FCC

隨后又有多次補充擴展
CJK Unified Ideographs Extension A
U+3400 – U+4DB5

CJK Unified Ideographs Extension B
U+20000 – U+2A6D6

CJK Unified Ideographs Extension C
U+2A700 – U+2B734

CJK Unified Ideographs Extension D
U+2B740 – U+2B81D

在這些extension之外,是幾個為了兼容性而保留的幾個區域
CJK Compatibility Ideographs U+F900 – U+FAD9
CJK Compatibility Supplement U+2F800 – U+2FA1D
(仔細看下面截屏, 每個字都等價對應到另一個code point)


說完了漢字, 后面相關的部分就比較亂了, 我就隨便猜測了:
CJK Phonetics and Symbols Area 偏旁部首吧 U+2E80-U+2EF3

Kangxi Radicals康熙字典里的偏旁部首? U+2F00 – U+2FD5

CJK Ideographic Description Characters 用來描述漢字結構的符號,如左右結構,上中下結構等 U+2FF0 - U+2FFB

CJK Symbols and Punctuation 符號 U+3000 -303F

Bopomofo 老拼音? U+3105-312D, U+31A0 – U+31B7

CJK strokes 筆畫 U+31C0 – U+31E3

Enclosed CJK Letters and Months 其它奇奇怪怪的東西, 包括月份等等, 懷疑有沒有人用啊 U+3220 – U+32CB

CJK Compatibility 另外很多奇葩的東西 U+3358-U+33FE

再有更過分的我就不都列了, 如易經八卦,麻將牌之類(是的, 麻將牌也能進Unicode, 震驚中)
其他
說完了UniHan, 說點兒別的相關的. 首先是平面分布的問題. 因為目前所有的unicode的code point都分布在0 到 0x10FFFF之間, 所以簡單粗暴的根據每個字符的最高5個bit,分成17層, 第0層就是0-0xFFFF;1層就是0x10000 =0x1FFFF;2層為0x20000 – 0x2FFFF;以此類推;最后一層(16層) 0x100000 – 0x10FFFF. (真的好險, 層數在多點兒就可以和地獄比比了)
Anyway, 漢字主要分布在0層,個別分布在2層. 因為幾乎所有人都基本工作在0層的,所以0層又稱為BMP(Basic Multilingual Plane).
最后在聊點encoding, 在windows平台上最常用的是UTF-16, 也就是用16bit為單位來表達unicode. 那么哪些變態的超過0xFFFF的字符怎么辦呢? 很簡單, 在unicode中0-0xFFFF中預留了一塊區域0xD800 – 0xDFFF是不允許任何字符集使用的, 這部分就被UTF-16用來編碼. 編碼的方式很簡單, 超過0xFFFF的字符最大是16層的0x10FFFF, 共21位, 所以不管三七二十一, 所有大於0xFFFF的字符在編碼前先減去0x10000, 這樣的結果就是最多只有20位了, 然后一分二, 分為高10位和低10位;高10為與0xD800或一下, 得到的結果就是在0xD800到0xDFFF之間, 叫lead surrogate或者high surrogates; 低10位與0xDC00或一個(就是做個加法), 得到的結果就是trail surrogate或low surrogates. 搞定.
多加一句, 所謂的UCS-2是UTF-16的前身, UCS最大只支持到0xFFFF, 他的字符是定寬的, 沒有surrogate一說, 它不能表達unicode的所有字符.
