輸入法詞庫解析(五)極點碼錶.mb
阿新 • • 發佈:2022-05-27
前 0x1A 個是版本資訊
0x1B ~ 0x11E 是詞庫的描述資訊,utf-16le 編碼
上圖部分解析為
五筆點兒詞庫2022春 QQ群313225526
生成日期:2022-3-17 18:36
第 0x11F,這個位元組表示所有用到的按鍵數,1A 即 26 鍵
0x120 開始,就是用到的按鍵,utf-16le
後面跟了 20 個空位元組
組詞規則,後面又跟了 20 個空位元組
下面 4 位元組,可能是特殊符號引導符
下面的部分就有規律了
每 4 個位元組一組,前兩個位元組表示一個字元,後兩個位元組從 00 00 ~ 29 00,一共 41 個值(可能是對應的首字母),中間有一些 FF FF FF FF
一直到 0x1B620
左右,有的詞庫可能會相差幾個位元組。
下面才是詞庫部分。
佔用位元組數 | 描述 |
---|---|
1 | 編碼長度 |
1 | 詞位元組長度 |
1 | 只有 0x64、0x32、0x10 幾個值,意義不明 |
取決於編碼長度 | 編碼,ascii |
取決於詞位元組長度 | 詞,utf-16le |
golang
實現(只讀 0x1B620 之後的碼錶):
func ParseJidianMb(rd io.Reader) Dict { ret := make(Dict, 1e5) // 初始化 tmp, _ := ioutil.ReadAll(rd) // 全部讀到記憶體 r := bytes.NewReader(tmp) r.Seek(0x1B620, 0) // 從 0x1B620 開始讀 // utf-16le 轉換 decoder := unicode.UTF16(unicode.LittleEndian, unicode.IgnoreBOM).NewDecoder() for r.Len() > 3 { codeLen, _ := r.ReadByte() if codeLen == 0xff { r.Seek(1, 1) continue } wordLen, _ := r.ReadByte() r.Seek(1, 1) // 丟掉一個位元組 codeSli := make([]byte, codeLen) r.Read(codeSli) wordSli := make([]byte, wordLen) r.Read(wordSli) wordSli, _ = decoder.Bytes(wordSli) ret.insert(string(codeSli), string(wordSli)) } return ret }