输入法词库解析(三)紫光拼音词库.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属性的值)值判断是否进行下一步运算或者输出等. ...
随机推荐
- NC20276 [SCOI2010]传送带
NC20276 [SCOI2010]传送带 题目 题目描述 在一个2维平面上有两条传送带,每一条传送带可以看成是一条线段.两条传送带分别为线段AB和线段CD.lxhgww在AB上的移动速度为P,在CD ...
- NC25136 [USACO 2006 Ope B]Cows on a Leash
NC25136 [USACO 2006 Ope B]Cows on a Leash 题目 题目描述 给定如图所示的若干个长条.你可以在某一行的任意两个数之间作一条竖线,从而把这个长条切开,并可能切开其 ...
- NC16783 [NOIP1998]拼数
NC16783 [NOIP1998]拼数 题目 题目描述 设有 \(n\) 个正整数(\(n ≤ 20\)),将它们联接成一排,组成一个最大的多位整数. 例如:\(n=3\) 时,\(3\) 个整数 ...
- STC8H开发(十三): I2C驱动DS3231高精度实时时钟芯片
目录 STC8H开发(一): 在Keil5中配置和使用FwLib_STC8封装库(图文详解) STC8H开发(二): 在Linux VSCode中配置和使用FwLib_STC8封装库(图文详解) ST ...
- 40+倍提升,详解 JuiceFS 元数据备份恢复性能优化之路
JuiceFS 支持多种元数据存储引擎,且各引擎内部的数据管理格式各有不同.为了便于管理,JuiceFS 自 0.15.2 版本提供了 dump 命令允许将所有元数据以统一格式写入到 JSON 文件进 ...
- 【RocketMQ】消息的消费
上一讲[RocketMQ]消息的拉取 消息消费 当RocketMQ进行消息消费的时候,是通过ConsumeMessageConcurrentlyService的submitConsumeRequest ...
- 第三天python3 字典
字典 dict 特点:key-value键值对的数据的集合 可变的.无序的.key不重复:非线性结构: 字典的初始化 d=dict() 或者 d = { } dict(**kwargs) 使用n ...
- 哈希-hash
一. 概念 1.引例 有线性表(1,75,324,43,1353,90,46,- ) 目的:查找值为90的元素 常见做法: 1.通过一维数组进行遍历查找 (依次比较)( O(n) ) 2.如果关键字 ...
- k8s QoS与pod驱逐
概述 QoS是Quality of Service的缩写,即服务质量.每个pod属于某一个QoS分类,而Kubernetes会根据pod的QoS级别来决定pod的调度.抢占调度和驱逐优先级,而且pod ...
- 如何在本地配置lemonlime和使用lemonlime测试交互题
如何在本地配置\(lemonlime\)和使用\(lemonlime\)测试交互题 \(lemonlime\)下载地址链接,提取码ae3z 点开\(lemonlime.exe\)然后编译器选择\(gc ...