Repository navigation
GBoard_Binary
Gboard 把用户词典以二进制文件 user_dict_3_3 保存在设备中。「Gboard user_dict_3_3」格式可以直接读写这个文件,用它替换设备上的词典,就能把电脑上的词库搬进 Gboard。
与「Gboard」格式的区别:
- Gboard:制表符文本,配合 Gboard 设置里的「字典 → 个人字典 → 导入」使用
-
Gboard user_dict_3_3:二进制的
user_dict_3_3,直接替换设备上的用户词典文件
二进制方式不受设置界面导入速度的限制,词库可以更大。
解决iOS Gboard无导入功能的问题
-
用深蓝词库转换,把词库转换成「Gboard user_dict_3_3」格式。
-
关闭 Gboard 进程,把生成的文件放到下面的路径,并改名为
user_dict_3_3:-
Android
/data/data/com.google.android.inputmethod.latin/files/user_dict_3_3 -
iOS(越狱)
/var/mobile/Containers/Shared/AppGroup/<AppGroup ID>/UserDict/user_dict_3_3
-
-
打开键盘,稍等几秒即可使用。
取出设备上的 user_dict_3_3(路径见上),用深蓝词库转换读入(输入格式选「Gboard user_dict_3_3」),再转换成需要的格式。
- 建议使用带注音的词库(如搜狗拼音文本词库、谷歌拼音词库),工具会直接采用词库给出的读音;纯词表只能按字表默认读音处理。
- 替换词典前建议先备份原来的
user_dict_3_3,替换后 Gboard 之前记住的词会丢失。 - 替换前务必彻底关闭 Gboard 进程,否则键盘会用内存里的旧词库覆盖文件。
- 词库里如果有 emoji 词条,需要在「高级设置 → 保留标点符号」中勾选该选项。
以下内容仅供想了解实现细节或需要自行处理该格式的人参考,普通使用不必阅读。
[16B 头] magic 96 A4 CB A7 | 0 | version=3 | 1
[proto0] field1 = Σ(所有 KEY 条目的 F1)
[proto1] field5 = FPT2 条目总数
"VariableValueLengthTrie"
"DATrie"
"DA-TRIE\0" + crc64 + 536B 结构 + 8×N 节点
FPT1(6 字节/行)
P-TABLE(4 字节/槽)
FPT2(14 字节/条)
查找链:拼音路径 → DA-trie 终端节点 → 该节点 base ÷ 6 得到 F1 行号 → F1 行给出 P-TABLE 槽号 → 槽里存放 FPT2 字节偏移 → 读出词条。
Gboard 用私用区(PUA)字节表示拼音,声调完全忽略(妈/麻/马/骂 同码):
c0 码 = { 0xEE, 声母索引, 0x80 } 缩写(只标声母)
c1 码 = { 0xEE, 声母索引, 韵母索引 } 完整
声母 24 个:0x81 零声母、0x82 b、0x83 c、0x84 ch、0x85 d、0x86 f、0x87 g、0x88 h、0x89 j、0x8a k、0x8b l、0x8c m、0x8d n、0x8e p、0x8f q、0x90 r、0x91 s、0x92 sh、0x93 t、0x94 w、0x95 x、0x96 y、0x97 z、0x98 zh
韵母 33 个:0x82 ang、0x83 ei、0x85 ai、0x86 in、0x87 iu、0x88 ong、0x89 ao、0x8a an、0x8b uai、0x8c en、0x8d iong、0x8e uan、0x8f ia、0x90 ing、0x91 ie、0x92 er、0x93 iao、0x94 ian、0x96 eng、0x97 iang、0x98 ui、0x9a uang、0x9b a、0x9c e、0x9d i、0x9e o、0x9f uo、0xa0 un、0xa1 u、0xa2 v(ü)、0xa3 ve、0xa4 ou、0xa5 ua
其余字符的处理:
- 汉字:3 字节 PUA 码
- ASCII 字母/数字:1 字节小写 ASCII
- ASCII 其它(空格、撇号、标点):直接丢弃
于是 m A上平安 变成 ma + 上平安,you'd就 变成 youd + 就,T恤 变成 t + 恤。
Emoji 与普通词条一样,拼音来自词库的注音。Gboard 的候选词本身会为 emoji 注音 ——
用户输入什么拼音、选中哪个 emoji,Gboard 就按那组拼音记住它。例如输入 eyu 选中 🐊,
以后输入 eyu 就能打出 🐊;输入 maoge 选中 🐱哥,同理。
所以转换时只要词库里有 emoji 的注音,直接沿用即可,工具不会去猜 emoji 读什么。
需要注意的是:emoji 是单个码点,但对应的拼音往往有多个音节(🐊 对应 e yu 两个音节),
解析时音节数与码点数并不一一对应。
导出时直接采用 entry.Code 的主编码,每个词对应一个拼音路径,与项目其他导出器保持一致。
- 带注音的输入(搜狗拼音、QQ 拼音、百度拼音、微软拼音、Rime、谷歌拼音等):使用词库给出的读音
- 纯词表输入:优先查项目
WordPinyin.txt的词组注音,否则取ChineseCode.txt中该字的默认读音
格式本身支持一个词对应多个拼音路径(官方词典里有这样的词,如「了」可以读 le 或 liao),导入时能正常解析;导出时每个词只写一个。
| 约束 | 违反后果 |
|---|---|
文件总长度按 8 字节对齐(末尾补 0x00) |
Gboard 拒绝并清空词典 |
CRC64 初值为多项式 0xAB0547580DAAC74E(不是 0) |
校验和不匹配,同样被拒绝 |
魔数写成字节序列 96 A4 CB A7
|
按 u32 小端写会变成 A7 CB A4 96,被拒绝 |
这三条的症状相同:词打不出来,且设备上的词典被 Gboard 重置成空文件。它们都不影响结构校验,只能靠逐字节比对已知可用的文件来排查。
| 字段 | 上限 |
|---|---|
| P-TABLE 槽号(23 位) | 8,388,607 ← 实际瓶颈 |
F1 行数 / FPT2 条目(u32) |
42.9 亿 |
DA-trie 节点(i32) |
21.4 亿 |
单条 F1.kind(u8) |
255 |
每词约 11 个槽,因此约 76 万词、250 MB 左右。
- P-TABLE 双索引:每个 FPT2 条目同时出现在
key_node的链和val_node的块中,所以F1.kind等于引用该节点的条目总数 - F1 行 6 字节:
[kind:u8][val:u16][slot_hi:u8][hash:u16],槽号slot = (val >> 1) | (slot_hi << 15) - DA-trie 终端节点的
base等于 6 乘 F1 行号 - 词表按 KEY 路径的字节序排序
- KEY 的 F1 值全局唯一,同音组出现平局会导致点选候选时死循环
| 问题 | 现象 | 原因 |
|---|---|---|
| 文件长度未对齐 | 词典被清空 | 末尾缺少填充 |
| CRC64 初值为 0 | 词典被清空 | 初值必须是多项式本身 |
| 魔数按 u32 写 | 词打不出但能学习 | 小端序把字节顺序倒过来 |
ue 未归一化 |
含 jue/que/xue/yue 的词整条丢失 |
项目字表写 jue,Gboard 写 jve
|
F1.kind 溢出 |
超长同音链查找失败 |
kind 是 u8,单链上限 255 |
| 数组引用被提前捕获 | trie 无限增长直至内存耗尽 |
Array.Resize 之后向旧数组赋值 |
| 边插入边记录终端节点 | 查找全部错位 | 节点重定位会搬移已有节点 |