输入法词库解析(六)QQ 拼音分类词库.qpyd
前言
.qpyd 是 QQ 拼音输入法 6.0 以下版本所用的词库格式,可以在 http://cdict.qq.pinyin.cn/v1/ 下载。
该格式解析的主要难点是其使用了 zlib 压缩,解压后的数据很好解析。
解析
原始文件
0x38 后跟的 4 字节表示压缩数据开始的字节。
0x44 后跟的 4 字节表示词条数。
0x60 - 0x16F 是词库的一些描述信息。
其余未知。
解压数据
使用了 zlib 格式。
我们看看解压后的数据是什么形式。
可以发现它分为两部分,前部分每 10 个一组,总长 10*词条数。
放到文本编辑器里分析一下,这里取了前后两部分前三条。
可以看到前部分是编码长和词长信息,后半部分 ascii 的编码 + utf-16le 的词条。
前半部分保存了所有词条的编码长,词长,索引位置。
| 占用字节数 | 描述 |
|---|---|
| 1 | 拼音的长度 |
| 1 | 词字节长 |
| 4 | 未知,全是00 00 80 3F |
| 4 | 词条的索引位置 |
后半部分就是词条本身了,拼音和词,词条之间都是紧挨着的。
前面是编码,框里的是词。
代码实现:
func (QqQpyd) Parse(filename string) Dict {
data, _ := os.ReadFile(filename)
r := bytes.NewReader(data)
ret := make(Dict, 0, r.Len()>>8)
var tmp []byte
// 0x38 后跟的是压缩数据开始的偏移量
r.Seek(0x38, 0)
startZip := ReadUint32(r)
// 0x44 后4字节是词条数
r.Seek(0x44, 0)
dictLen := ReadUint32(r)
// 0x60 到zip数据前的一段是一些描述信息
r.Seek(0x60, 0)
head := make([]byte, startZip-0x60)
r.Read(head)
// headStr, _ := Decode(head, "UTF-16LE")
// fmt.Println(headStr) // 打印描述信息
// 解压数据
zrd, err := zlib.NewReader(r)
if err != nil {
log.Panic(err)
}
defer zrd.Close()
buf := new(bytes.Buffer)
buf.Grow(r.Len())
_, err = io.Copy(buf, zrd)
if err != nil {
log.Panic(err)
}
// 解压完了
r.Reset(buf.Bytes())
for i := 0; i < dictLen; i++ {
// 指向当前
r.Seek(int64(10*i), 0)
// 读码长、词长、索引
addr := make([]byte, 10)
r.Read(addr)
idx := BytesToInt(addr[6:]) // 后4字节是索引
r.Seek(int64(idx), 0) // 指向索引
// 读编码,自带 ' 分隔符
tmp = make([]byte, addr[0])
r.Read(tmp)
code := string(tmp)
// 读词
tmp = make([]byte, addr[1])
r.Read(tmp)
word, _ := util.Decode(tmp, "UTF-16LE")
ret = append(ret, Entry{word, strings.Split(code, "'"), 1})
}
return ret
}
输入法词库解析(六)QQ 拼音分类词库.qpyd的更多相关文章
- 用C语言将搜狗输入法词库转换成QQ拼音输入法词库
搜狗输入法词库格式: 'ni'kan'xia 你看下 'ni'kan'xia'gai'hou 你看下改后 'ni'kan'xing'ma 你看行吗 'ni'kan'zen'me'yang 你看怎么样 ...
- JavaScript Emoji 表情库_js 类似于qq微信的表情库
摘要: emoji就是表情符号,来自日语词汇“絵文字”(假名为“えもじ”,读音即emoji).emoji的创造者是日本人栗田穰崇(Shigetaka Kurita),他将目光投向儿时的各种元素以获取灵 ...
- QQ五笔词库转拼音词库小工具
参考文章<用QQ拼音打五笔>中提供的信息而制作的小工具,功能是将QQ五笔导出词库文件转换为QQ拼音自定义短语使用的.ini格式文件,这样就可以使用QQ拼音进行五笔拼音混输了. 混输效果不错 ...
- 输入法词库解析(四)百度分类词库.bdict(.bcd)
前言 .bdict 是百度的分类词库格式,可以在 https://shurufa.baidu.com/dict 下载. 手机百度的分类词库格式 .bcd 是一样的,可以在 https://mime.b ...
- 输入法词库解析(三)紫光拼音词库.uwl
详细代码:https://github.com/cxcn/dtool 前言 .uwl 是紫光拼音输入法(现在叫华宇拼音输入法)使用的词库. 解析 紫光的词库有点复杂,拼音用的索引,但是拼音表没有写在词 ...
- 输入法词库解析(二)搜狗拼音细胞词库.scel(.qcel)
详细代码:https://github.com/cxcn/dtool 前言 .scel 是搜狗拼音输入法所使用的细胞词库格式,可以在 https://pinyin.sogou.com/dict/ 下载 ...
- 输入法词库解析(五)极点码表.mb
详细代码:https://github.com/cxcn/dtool 前言 mb 是极点五笔的码表格式. 解析 偏移量 描述 0x00 版本信息 0x1B 码表介绍 0x11F 所用到的按键数 0x1 ...
- 评价qq拼音输入法
我目前正在使用qq拼音输入法,从人机交互设计方面,我对qq输入法从用户界面.记住用户选择.短期刺激和长期使用的好处坏处.不让用户犯简单错误这四个方面进行了评价. 1.从用户界面方面: qq输入法用户界 ...
- 评价正在使用输入法软件产品----QQ拼音输入法
评价一下大家手头正在使用输入法或者搜索类的软件产品. 我现在使用的是系统自带的QQ拼音输入法,以前使用的是搜狗拼音输入法,后来发现可能由于我的系统重装过好几次,搜狗输入法也重装了好几次,而每次都删不干 ...
随机推荐
- 多校联训 DS 专题
CF1039D You Are Given a Tree 容易发现,当 \(k\) 不断增大时,答案不断减小,且 \(k\) 的答案不超过 \(\lfloor\frac {n}{k}\rfloor\) ...
- Spring框架系列(13) - SpringMVC实现原理之DispatcherServlet的初始化过程
前文我们有了IOC的源码基础以及SpringMVC的基础,我们便可以进一步深入理解SpringMVC主要实现原理,包含DispatcherServlet的初始化过程和DispatcherServlet ...
- Pytorch从0开始实现YOLO V3指南 part2——搭建网络结构层
本节翻译自:https://blog.paperspace.com/how-to-implement-a-yolo-v3-object-detector-from-scratch-in-pytorch ...
- Eclipse拷贝动态的web工程
1.选中需要拷贝的工程,CTRL+C,然后CTRL+V 2.在web动态工程中,还需要选中新拷贝工程,右键选中properties,然后搜索web,--->Web Project Setttin ...
- Hadoop-HA 搭建高可用集群Hadoop Zookeeper
Hadoop Zookeeper 搭建(一) 一.准备工作 VMWARE虚拟机 CentOS 7 系统 虚拟机1:master 虚拟机2:node1 虚拟机3:node2 时间同步 ntpdate n ...
- PySide6/PyQt开发xml编辑器(1)
QTreeWidget折叠子项(折叠当前项的所有子项) 本文仅供本人知识总结使用,所以内容会比较浅显,不喜勿喷. 目录 QTreeWidget折叠子项(折叠当前项的所有子项) 目录 一.仅折叠子项 二 ...
- PhoneBean实体类的封装和map输出键值对的设置
之前我们写好了bean类型.现在我们再看看这个需求中,map和reduce各自的流程. Map阶段: 字段切分以后保留如下字段:以第一行为例,就保留13726230503112 2481 24681 ...
- Thymeleaf是什么?该如何使用。
先了解Thymeleaf是什么 1. Thymeleaf 简介 Thymeleaf 是新⼀代 Java 模板引擎,与 Velocity.FreeMarker 等传统 Java 模板引擎不同,Thyme ...
- Odoo14 ir.config_parameter 系统参数
1 # 文件上传大小限制 2 web.max_file_upload_size = 128 * 1024 * 1024 # 128m 3 # 以上是odoo中设置上传文件的最大size,但如果你用了n ...
- PostgreSQL 备份
# WAL日志: # 我们对数据库的增删改查创建之前先是将sql语句记录在WAL日志中, # 只有日志记录刷新到磁盘后,才能写入数据库文件. # 遵从这个过程,不需要在每个事务提交时都刷新数据页到数据 ...