详细代码:https://github.com/cxcn/dtool

前言

.uwl 是紫光拼音输入法(现在叫华宇拼音输入法)使用的词库。

解析

紫光的词库有点复杂,拼音用的索引,但是拼音表没有写在词库里。

好在深蓝词库转换工具已经解析好了,这部分就跳过了。

词长和拼音长关系密切,要注意。

主要词库部分每 1024 字节为一段(分段意义何在?)

前两个字节未知,第 3 个字节表示字符编码格式 0x08 是 GBK,0x09 是 UTF-16LE。

范围 描述
0x04 - 0x23 词库名
0x24 - 0x43 词库作者
0x44 - 0x47 词条数
0x48 - 0x4B 分为几段

0x4C - 0xBFF 未知。

从 0xC00 开始,每 1024 为一段,一段有个 16 字节的头信息。

4 个字节为一组,分别表示:第几段,未知,未知,词条占用字节数(小于 1024-16)。

占用字节数 描述
a 1 词占用字节 + 1(所以总是奇数),可能大于 0x80
b 1 拼音长度的一半,前 4 位(总是偶数)意义不明
2 词频
b%0x10*2 + a/0x80 拼音索引
a%0x80 - 1

代码实现:

var uwlSm = []string{
"", "b", "c", "ch", "d", "f", "g", "h", "j", "k", "l", "m", "n",
"p", "q", "r", "s", "sh", "t", "w", "x", "y", "z", "zh",
} var uwlYm = []string{
"ang", "a", "ai", "an", "ang", "ao", "e", "ei", "en", "eng", "er",
"i", "ia", "ian", "iang", "iao", "ie", "in", "ing", "iong", "iu",
"o", "ong", "ou", "u",
"ua", "uai", "uan", "uang", "ue", "ui", "un", "uo", "v",
} func (ZiguangUwl) Parse(filename string) Dict {
data, _ := os.ReadFile(filename)
r := bytes.NewReader(data)
ret := make(Dict, 0, r.Len()>>8)
r.Seek(2, 0)
// 编码格式,08 为 GBK,09 为 UTF-16LE
encoding, _ := r.ReadByte() // 分段
r.Seek(0x48, 0)
partLen := ReadUint32(r)
for i := 0; i < partLen; i++ {
r.Seek(0xC00+int64(i)<<10, 0)
ret = parseZgUwlPart(r, ret, encoding)
} return ret
} func parseZgUwlPart(r *bytes.Reader, ret Dict, e byte) Dict {
r.Seek(12, 1)
// 词条占用字节数
max := ReadUint32(r)
// 当前字节
curr := 0
for curr < max {
head := make([]byte, 4)
r.Read(head)
// 词长 * 2
wordLen := head[0]%0x80 - 1
// 拼音长
codeLen := head[1]<<4>>4*2 + head[0]/0x80
// 频率
freq := BytesToInt(head[2:])
// fmt.Println(freqSli, freq)
curr += int(4 + wordLen + codeLen*2) // 拼音
code := make([]string, 0, codeLen)
for i := 0; i < int(codeLen); i++ {
bsm, _ := r.ReadByte()
bym, _ := r.ReadByte()
smIdx := bsm & 0x1F
ymIdx := (bsm >> 5) + (bym << 3)
// fmt.Println(bsm, bym, smIdx, ymIdx)
if bym >= 0x10 || smIdx >= 24 || ymIdx >= 34 {
break
}
code = append(code, uwlSm[smIdx]+uwlYm[ymIdx])
// fmt.Println(smIdx, ymIdx, uwlSm[smIdx]+uwlYm[ymIdx])
} // 词
tmp := make([]byte, wordLen)
r.Read(tmp)
var word string
switch e {
case 0x08:
word, _ = util.Decode(tmp, "GBK")
case 0x09:
word, _ = util.Decode(tmp, "UTF-16LE")
}
// fmt.Println(string(word))
ret = append(ret, Entry{word, code, freq})
}
return ret
}

参考资料:

深蓝词库转换

输入法词库解析(三)紫光拼音词库.uwl的更多相关文章

  1. 开源 JSON 库解析性能对比( Jackson / Json.simple / Gson )

    Json 已成为当前服务器与 web 应用之间数据传输的公认标准. 微服务及分布式架构经常会使用 Json 来传输此类文件,因为这已经是 webAPI 的事实标准. 不过正如许多我们习以为常的事情一样 ...

  2. python爬虫之urllib库(三)

    python爬虫之urllib库(三) urllib库 访问网页都是通过HTTP协议进行的,而HTTP协议是一种无状态的协议,即记不住来者何人.举个栗子,天猫上买东西,需要先登录天猫账号进入主页,再去 ...

  3. 输入法词库解析(四)百度分类词库.bdict(.bcd)

    前言 .bdict 是百度的分类词库格式,可以在 https://shurufa.baidu.com/dict 下载. 手机百度的分类词库格式 .bcd 是一样的,可以在 https://mime.b ...

  4. 输入法词库解析(二)搜狗拼音细胞词库.scel(.qcel)

    详细代码:https://github.com/cxcn/dtool 前言 .scel 是搜狗拼音输入法所使用的细胞词库格式,可以在 https://pinyin.sogou.com/dict/ 下载 ...

  5. 输入法词库解析(五)极点码表.mb

    详细代码:https://github.com/cxcn/dtool 前言 mb 是极点五笔的码表格式. 解析 偏移量 描述 0x00 版本信息 0x1B 码表介绍 0x11F 所用到的按键数 0x1 ...

  6. 使用adns库解析域名

    1. adns.adns-python库简介 adns库是一个可进行异步非阻塞解析域名的库,主要使用C语言编写,在linux平台下运行.使用adns库进行域名解析效率非常,著名的开源网络爬虫larbi ...

  7. 用jieba库统计文本词频及云词图的生成

    一.安装jieba库 :\>pip install jieba #或者 pip3 install jieba 二.jieba库解析 jieba库主要提供提供分词功能,可以辅助自定义分词词典. j ...

  8. [深入浅出Windows 10]QuickCharts图表控件库解析

    13.4 QuickCharts图表控件库解析     QuickCharts图表控件是Amcharts公司提供的一个开源的图表控件库,这个控件库支持WPF.Silverlight.和Windows等 ...

  9. Struts2的标签库(三)——控制标签

    Struts2的标签库(三) --控制标签 1.if/elseif/else标签 用于分支控制,取代JSP中的if语句,根据一个boolean(test属性的值)值判断是否进行下一步运算或者输出等. ...

随机推荐

  1. Redis docker 主从模式与哨兵sentinel

    更多技术记录,请参考软件开发 | 编程 | RustFisher 为实现redis的高可用,我们采用主从模式加哨兵的方法. 一主二从三哨兵,共启动6个redis容器.本文示例在同一个服务器上进行操作. ...

  2. 攻防世界pwn题:Recho

    0x00:查看文件信息 一个64位二进制文件,canary和PIE保护机制没开. 0x01:用IDA进行静态分析 分析:主程序部分是一个while循环,判断条件是read返回值大于0则循环.函数ato ...

  3. Tapdata肖贝贝:实时数据引擎系列(三) - 流处理引擎对比

      摘要:本文将选取市面上一些流计算框架包括 Flink .Spark .Hazelcast,从场景需求出发,在核心功能.资源与性能.用户体验.框架完整性.维护性等方面展开分析和测评,剖析实时数据框架 ...

  4. Proxmox6.2简单配置

    刻录: 使用rufus+GPT+DD方式写入U盘 一.更换国内源: 1)删除企业源 mv /etc/apt/sources.list.d/pve-enterprise.list /etc/apt/so ...

  5. ERROR .web.servlet.DispatcherServlet - Context initialization failed

    自己创建了一个SSM 项目,使用maven的tomcat7 运行报错 ERROR .web.servlet.DispatcherServlet - Context initialization fai ...

  6. @Document注解与Lombok的区别

  7. 思维导图学《On Java》基础卷

    说明 原来读过 <Java 编程思想(第 4 版)>,但是这个版本还是基于 Java 5 讲解.由于 Java 8 做出了非常大的改进(是 Java 变化最大的版本),且截止到 2022- ...

  8. go-zero单体服务使用泛型简化注册Handler路由

    一.Golang环境安装及配置Go Module https://go-zero.dev/cn/docs/prepare/golang-install mac OS安装Go# 下载并安装Go for ...

  9. [eJOI2019]异或橙子 题解

    简要题面 维护一个数据结构,支持单点修改,询问区间所有子区间的异或和的异或和 . 做法 首先,题目要求所有子区间的异或和的异或和,发现每个元素异或两次就变成 \(0\),所以考虑统计每个元素出现的次数 ...

  10. Mpvue1.0+Python3.7+Django2.0.4实现微信小程序的支付功能

    原文转载自「刘悦的技术博客」https://v3u.cn/a_id_112 其实微信支付有很多种形式,刷脸,扫码,APP支付,小程序支付等,这边只说明小程序支付的实现,不过原理上都大同小异. 首先,需 ...