跳到正文
>sdcb.ai
新上线 · 2026.10React · TypeScript · Cloudflare Pages

哪个字忘了怎么拆,查一下就知道

86 版五笔用了很多年,偶尔还是会卡在「鼎」「凹」这种字上。大多数反查网站只给一个编码,我想知道的是为什么:拆成哪几个字根、每个字根是哪几笔、最后一码是不是识别码。

胜
shēng / shèng
etgg

月 + 撇 + 青字头,只有 3 个字根,补末笔字型识别码:末笔横、左右型 → 11 区位 → G。

条微软五笔词库记录
53.4 万
个汉字可查
2.8 万
个字带田字格图解
9,568
个 JSON 分片,按需加载
2,686

功能

不只是反查一个编码

整句

「今天吃什么」最少要按几下?

整句不在词库里,硬套造词规则推出来的编码根本打不出来。这里把句子切成词库里真实存在的词,每段代价 = 编码位数 + 上屏键,求总键数最少的切法。

src/lib/plan.ts
// '' = auto commit, ' ' = space, '2'..'9' = pick
function commitKey(code: string, rank: number, n: number) {
  if (rank > 9) return null
  if (code.length === 4 && n === 1) return ''
  return rank === 1 ? ' ' : String(rank)
}

推荐打法

只用第一候选,不用记选重数字

14键
今天wygd␣
吃ktn␣
什么wftc␣

优化打法

允许数字选重,键数更少

10键
今天wygd␣
吃什么kwtc4
在 wubi.sdcb.ai 上看完整推导
scripts/extract-ms-lex.mjs
// Record layout: u16 len | u16 weight | u16 codeLen | 4 x u16 code | utf16le word | u16 0
let p = 0xa8
while (p + 2 <= b.length) {
  const len = b.readUInt16LE(p)
  if (len === 0) break
  const weight = b.readUInt16LE(p + 2)
  const codeLen = b.readUInt16LE(p + 4)
  const code = b.toString('utf16le', p + 6, p + 6 + codeLen * 2)
  const word = b.toString('utf16le', p + 14, p + len - 2)
  lines.push(`${code}\t${word}\t${weight}`)
  p += len
}

数据

和你电脑上的微软五笔一模一样

网上流传的 86 码表版本很多,简码、词组和候选顺序都不一致。这里的编码直接解析自 Windows 自带的 ChsWubiNew.lex:格式没有公开文档,但结构不复杂,一共 53 万多条,同一编码下按权重排序就是输入法里的候选顺序。

所以网站上写着「第 2 候选,需按 2」,你在自己电脑上也是按 2。

算法

真正花功夫的:把笔画和字根对上

字根拆分来自我的另一个项目 search-wubi,笔画矢量来自 Make Me a Hanzi,但两者之间没有“第几笔属于哪个字根”的对应,现成标好的只有两千多个字。剩下的靠算法补齐:

  1. 01
    2,218

    已标注的字

    search-wubi 里现成标好“哪几笔属于哪个字根”的字。

  2. 02
    学习

    字根 → 笔画序列

    统计每个字根通常由哪几种笔画(横竖撇点折)组成。

  3. 03
    6,023

    回溯严格匹配

    把字的笔画序列逐段匹配到字根上,多解时按统计打分。

  4. 04
    496

    放宽 + 编辑距离

    允许段内笔序调整,最后用编辑距离兜底,界面标注“自动推断”。

用已知答案的字做验证,约 95% 能完全对上;最终 8,737 个字拿到了逐笔对应的田字格,常用字基本覆盖。

下次忘了,查一下就行

手机电脑都能用,不用注册,没有广告。项目以 AGPL-3.0 协议开源,发现拆错的字欢迎提 issue。

相关文章