输入法词库解析(三)紫光拼音词库.uwl
前言
.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的更多相关文章
- 开源 JSON 库解析性能对比( Jackson / Json.simple / Gson )
Json 已成为当前服务器与 web 应用之间数据传输的公认标准. 微服务及分布式架构经常会使用 Json 来传输此类文件,因为这已经是 webAPI 的事实标准. 不过正如许多我们习以为常的事情一样 ...
- python爬虫之urllib库(三)
python爬虫之urllib库(三) urllib库 访问网页都是通过HTTP协议进行的,而HTTP协议是一种无状态的协议,即记不住来者何人.举个栗子,天猫上买东西,需要先登录天猫账号进入主页,再去 ...
- 输入法词库解析(四)百度分类词库.bdict(.bcd)
前言 .bdict 是百度的分类词库格式,可以在 https://shurufa.baidu.com/dict 下载. 手机百度的分类词库格式 .bcd 是一样的,可以在 https://mime.b ...
- 输入法词库解析(二)搜狗拼音细胞词库.scel(.qcel)
详细代码:https://github.com/cxcn/dtool 前言 .scel 是搜狗拼音输入法所使用的细胞词库格式,可以在 https://pinyin.sogou.com/dict/ 下载 ...
- 输入法词库解析(五)极点码表.mb
详细代码:https://github.com/cxcn/dtool 前言 mb 是极点五笔的码表格式. 解析 偏移量 描述 0x00 版本信息 0x1B 码表介绍 0x11F 所用到的按键数 0x1 ...
- 使用adns库解析域名
1. adns.adns-python库简介 adns库是一个可进行异步非阻塞解析域名的库,主要使用C语言编写,在linux平台下运行.使用adns库进行域名解析效率非常,著名的开源网络爬虫larbi ...
- 用jieba库统计文本词频及云词图的生成
一.安装jieba库 :\>pip install jieba #或者 pip3 install jieba 二.jieba库解析 jieba库主要提供提供分词功能,可以辅助自定义分词词典. j ...
- [深入浅出Windows 10]QuickCharts图表控件库解析
13.4 QuickCharts图表控件库解析 QuickCharts图表控件是Amcharts公司提供的一个开源的图表控件库,这个控件库支持WPF.Silverlight.和Windows等 ...
- Struts2的标签库(三)——控制标签
Struts2的标签库(三) --控制标签 1.if/elseif/else标签 用于分支控制,取代JSP中的if语句,根据一个boolean(test属性的值)值判断是否进行下一步运算或者输出等. ...
随机推荐
- Redis docker 主从模式与哨兵sentinel
更多技术记录,请参考软件开发 | 编程 | RustFisher 为实现redis的高可用,我们采用主从模式加哨兵的方法. 一主二从三哨兵,共启动6个redis容器.本文示例在同一个服务器上进行操作. ...
- 攻防世界pwn题:Recho
0x00:查看文件信息 一个64位二进制文件,canary和PIE保护机制没开. 0x01:用IDA进行静态分析 分析:主程序部分是一个while循环,判断条件是read返回值大于0则循环.函数ato ...
- Tapdata肖贝贝:实时数据引擎系列(三) - 流处理引擎对比
摘要:本文将选取市面上一些流计算框架包括 Flink .Spark .Hazelcast,从场景需求出发,在核心功能.资源与性能.用户体验.框架完整性.维护性等方面展开分析和测评,剖析实时数据框架 ...
- Proxmox6.2简单配置
刻录: 使用rufus+GPT+DD方式写入U盘 一.更换国内源: 1)删除企业源 mv /etc/apt/sources.list.d/pve-enterprise.list /etc/apt/so ...
- ERROR .web.servlet.DispatcherServlet - Context initialization failed
自己创建了一个SSM 项目,使用maven的tomcat7 运行报错 ERROR .web.servlet.DispatcherServlet - Context initialization fai ...
- @Document注解与Lombok的区别
- 思维导图学《On Java》基础卷
说明 原来读过 <Java 编程思想(第 4 版)>,但是这个版本还是基于 Java 5 讲解.由于 Java 8 做出了非常大的改进(是 Java 变化最大的版本),且截止到 2022- ...
- go-zero单体服务使用泛型简化注册Handler路由
一.Golang环境安装及配置Go Module https://go-zero.dev/cn/docs/prepare/golang-install mac OS安装Go# 下载并安装Go for ...
- [eJOI2019]异或橙子 题解
简要题面 维护一个数据结构,支持单点修改,询问区间所有子区间的异或和的异或和 . 做法 首先,题目要求所有子区间的异或和的异或和,发现每个元素异或两次就变成 \(0\),所以考虑统计每个元素出现的次数 ...
- Mpvue1.0+Python3.7+Django2.0.4实现微信小程序的支付功能
原文转载自「刘悦的技术博客」https://v3u.cn/a_id_112 其实微信支付有很多种形式,刷脸,扫码,APP支付,小程序支付等,这边只说明小程序支付的实现,不过原理上都大同小异. 首先,需 ...