1. 程式人生 > 其它 >輸入法詞庫解析(五)極點碼錶.mb

輸入法詞庫解析(五)極點碼錶.mb

前 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
}