搜狗输入法ng版导入细胞词库过程的简要分析

news/2024/10/11 20:32:34

今天有点时间,对deepin/uos上的搜狗输入法ng版导入细胞词库的行为做了一下分析,过程如下:

1.在属性设置界面,用户选择.scel细胞词库文件,输入法对.scel的文件头进行验证,如果是 40 15 00 00 44 43 53 01 01,则验证通过,进行下一步操作。

然而,在Windows下导入txt文件生成的细胞词库的文件头是 40 15 00 00 D2 6D 53 01 01,搜狗输入法ng版会把词库文件以一个随机的名称扔到 ~/.config/cpis/sogou/attachment目录下,然后不管了。

但是却又提示用户导入成功,其实是没有进行导入操作,词库管理列表中也没有,这种操作很容易误导用户。其实使用txt导入的词库文件与官方的词库并没有什么区别,在后面可以使用脚本导入之后,使用上也是与官方词库无异。

2.在输入法对头文件验证通过之后,对词库文件的特定数据区间进行读取,获取属性信息,具体的偏移量如下:

# 词库的偏移区间与意义:词库来源:0x004-0x005(44 43为官方词库,D2 6D为用户自定义词库)
词库ID(id):0x001C-0x0026
词库生成时间戳(date):0x011C-0x011F
词库词条数量(words):0x124-0x127
词库名称(name):0x130-0x337
词库类别(type):0x338-0x53F
词库备注(remark):0x540-0xD3F
词库示例词(enumernate):0xD40-0x153F

然后将.scel词库文件,以词库id为名称,复制到 ~/.config/cpis/sogou/pcpy/scd,

将词库属性信息添加到词库列表文件 ~/.config/cpis/sogou/pcpy/scd/list.ini。

词库列表文件格式如下:

[15097]
id = 15097
name = 成语俗语【官方推荐】
type = 成语
remark = 官方推荐,词条来源于网友贡献!
enumernate = 各人自扫门前雪休管他人瓦上霜 拳头上立得人胳膊上走得路 即以其人之道还治其人之身 以其人之道还治其人之身 只要功夫深铁杵磨成针 知之为知之不知为不知
words = 46791
date = 1370515881
enabled = true

这样,在输入法的词库管理界面,就可以看到导入的词库,和相关的属性信息了。

对以上的操作进行复现的bash脚本:

#!/bin/bash# parse_scel.sh
# 用途:将用户输入的搜狗细胞词库文件,解析词库ID、词库名称、类别、备注、词条数、生成时间、词库来源、示例词并显示。# 检查输入参数
if [ "$#" -ne 1 ]; thenecho "用法: $0 <搜狗细胞词库路径>"exit 1
fiBINARY_FILE="$1"# 检查文件是否存在
if [ ! -f "$BINARY_FILE" ]; thenecho "错误: 文件 '$BINARY_FILE' 不存在。请检查文件路径。"exit 1
fi# 提取文件头
HEX_HEADER=$(hexdump -v -s 0 -n 9 -e '1/1 "%02x"' "$BINARY_FILE")# 检查文件头
if [[ "$HEX_HEADER" != "40150000d26d530101" && "$HEX_HEADER" != "401500004443530101" ]]; thenecho "$BINARY_FILE 似乎不是搜狗细胞词库,请检查。"exit 1
fi# 读取指定偏移量区间的数据并将其转为 UTF-16LE 的字符串,再转换为 UTF-8
extract_section_utf16le() {local start=$1local end=$2# 确保提取的字节数为偶数local length=$((($end - $start + 1) / 2 * 2))hexdump -v -s "$start" -n $length -e '1/1 "%02x"' "$BINARY_FILE" |xxd -r -p | iconv -f UTF-16LE -t UTF-8 | tr -d '\0' | tr '\n' ' '  # 转换 UTF-16LE 到 UTF-8,并去除空字符,替换换行符为空格
}# 读取指定偏移量区间的数据,过滤换行符,并将其转为 UTF-16LE 的字符串,再转换为 UTF-8
extract_example_utf16le() {local start=$1local end=$2local length=$((($end - $start + 1) / 2 * 2))# 读取字节,替换 0D 00 20 0020 00,去除换行符,然后转换为 UTF-8(有一些词库的示例词存在换行符)hexdump -v -s "$start" -n "$length" -e '1/1 "%02x"' "$BINARY_FILE" | sed 's/0d002000/2000/g' | xxd -r -p | iconv -f UTF-16LE -t UTF-8 | tr -d '\0'
}extract_entry_count() {# 读取 0x124 - 0x127 区间的 4 个字节,并确保转换为小端格式local hex_count=$(hexdump -v -s 0x124 -n 4 -e '1/1 "%02x"' "$BINARY_FILE")# 确保是偶数长度,去掉最后一个字符(如果是奇数)if [ $(( ${#hex_count} % 2 )) -ne 0 ]; thenhex_count="${hex_count:0: -1}"fi# 去除尾部的 "00" 字节hex_count="${hex_count%%00*}"# 初始化词条数local entry_count=0for (( i=0; i<${#hex_count}; i+=2 )); do# 将小端格式转换为十进制数entry_count=$((entry_count + 0x${hex_count:i:2} * (256 ** (i / 2))))done# 输出词条数量,去掉前面的空格echo "$entry_count"
}# 提取时间戳并转换为日期时间
timestamp_hex=$(hexdump -v -s 0x011C -n 4 -e '1/4 "%08x"' "$BINARY_FILE")
timestamp=$((16#$timestamp_hex))  # 将十六进制转换为十进制
extract_timestamp() {# 显示日期格式和原始时间戳echo "$(date -d @"$timestamp") (时间戳:$timestamp)"
}# 检查词库源类型
extract_library_source() {# 根据前面获取的文件头$HEX_HEADER变量判断词库来源if [ "$HEX_HEADER" == "40150000d26d530101" ]; thenecho "用户自定义词库"elif [ "$HEX_HEADER" == "401500004443530101" ]; thenecho "官方词库"fi
}# 偏移量区间 (以字节为单位)
ID_START=0x001C
ID_END=0x0026
NAME_START=0x130
NAME_END=0x337
CATEGORY_START=0x338
CATEGORY_END=0x53F
REMARK_START=0x540
REMARK_END=0xD3F
EXAMPLE_START=0xD40
EXAMPLE_END=0x153F# 提取信息
dictionary_id=$(extract_section_utf16le $ID_START $ID_END)
dictionary_name=$(extract_section_utf16le $NAME_START $NAME_END)
dictionary_category=$(extract_section_utf16le $CATEGORY_START $CATEGORY_END)
dictionary_remark=$(extract_section_utf16le $REMARK_START $REMARK_END)
dictionary_example=$(extract_example_utf16le $EXAMPLE_START $EXAMPLE_END)
dictionary_entry_count=$(extract_entry_count)
dictionary_timestamp=$(extract_timestamp)
library_source=$(extract_library_source)# 输出提取的信息
echo "编号(id): $dictionary_id"
echo "名称(name): $dictionary_name"
echo "类别(type): $dictionary_category"
echo "备注(remark): $dictionary_remark"
echo "词条数(words): $dictionary_entry_count"
echo "示例词(enumernate): $dictionary_example"
echo "生成时间(date): $dictionary_timestamp"
echo "来源: $library_source"# 说明:
# 词库的偏移区间与意义:# 词库来源:0x004-0x00544 43为官方词库,D2 6D为用户自定义词库)
# 词库ID:0x001C-0x0026
# 词库生成时间戳:0x011C-0x011F
# 词库词条数量:0x124-0x127
# 词库名称:0x130-0x337
# 词库类别:0x338-0x53F
# 词库备注:0x540-0xD3F
# 词库示例词:0xD40-0x153F# 生成搜狗输入法ng版词库列表 id_list.ini
create_import_file() {local CWD=$(dirname "$BINARY_FILE")  # 获取文件所在的目录local ini_file_name=""$dictionary_id"_list.ini"local ini_file_path="$CWD/$ini_file_name"# 创建 .ini 文件并写入内容cat <<EOF > "$ini_file_path"
[$dictionary_id]
id = $dictionary_id
name = $dictionary_name
type = $dictionary_category
remark = $dictionary_remark
enumernate = $dictionary_example
words = $dictionary_entry_count
date = $timestamp
enabled = true
EOF# 复制词库文件为 $dictionary_idcp "$BINARY_FILE" "$CWD/$dictionary_id"echo " "echo "词库导入方法:"echo""$dictionary_id" 文件复制到 "~/.config/cpis/sogou/pcpy/scd""echo""$ini_file_name" 文件合并到 "~/.config/cpis/sogou/pcpy/scd/list.ini""
}# 创建词库导入文件
create_import_file

 脚本运行截图:

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.ryyt.cn/news/70374.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈,一经查实,立即删除!

相关文章

花指令与anti-debug

花指令 anti-Debugptrace反调试 (1) ptrace系统调从名字上看是用于进程跟踪的,它提供了父进程可以观察和控制其子进程执行的能力,并允许父进程检查和替换子进程的内核镜像(包括寄存器)的值。其基本原理是: 当使用了ptrace跟踪后,所有发送给被跟踪的子进程的信号(除了SIGKILL),都…

禁止嵌套 iframe

vim /etc/nginx/nginx.conf 在:http 中加入:server { add_header X-Frame-Options "SAMEORIGIN"; } -----------------如:------------------------------------------ -------------------------------------------- 重启: cd /usr/sbin ./nginx -s relo…

诸多注解的作用

@Configuration标明这个类是一个配置类 @ComponentScan()用于设定扫描路径,此注解只能添加一次,多个注解用数组格式 @Scope注解是 Spring IOC 容器中的一个作用域,@Scope(singleton)标明为单例对象(默认也是单例),@Scope(prototype)标明为多例对象 影响Servlet生命周期的…

最终的方案

每个人维护一个歌单,建议一周一随,直接随出来几个歌单编号,由个人直接来决定最终歌曲,已经选过的歌单会等最后选完再重新计入。(两个机房的都可以贡献歌单) 现在建立新的歌单,曾经的那个仅供参考。 规则与上次相同。征求歌单!!! 原公告地址: 《公告》 CLOI在此向其…

南沙C++信奥赛陈老师解一本通题 1950:【10NOIP普及组】接水问题

​ 【题目描述】学校里有一个水房,水房里一共装有m个龙头可供同学们打开水,每个龙头每秒钟的供水量相等,均为1。 现在有n 名同学准备接水,他们的初始接水顺序已经确定。将这些同学按接水顺序从1到n 编号,i号同学的接水量为w。接水开始时,1 到m 号同学各占一个水龙头,并同…

如何快速上手一个新项目?

前言 最近知识星球中有小伙伴问我:如何快速上手一个新项目? 这个问题是一个公共问题,估计很多换了公司的小伙都想问这个问题。 我在工作的这些年当中,换过几次工作,接手过同事的一些项目,需要经常上手一些不同类型的新项目。 今天这篇文章跟大家一起聊聊我的一些总结和思…

Nacos服务相关

nacos是阿里开源的一款用于微服务的多服务管理工具,通过服务注册进入内部服务器可以看到注册的服务; 服务注册原理: 在微服务远程调用的过程中,包括两个角色: 服务调用者,调用其他服务的接口,服务提供者,提供接口给其他服务调用 在大型微服务项目中,服务提供者的数量会…

熵权法

熵是热力学的一个物理概念,是体系混乱度或无序度的度量,熵越大表示系统越乱(即携带的信息越少),熵越小表示系统越有序(即携带的信息越多)。 信息熵借鉴了热力学中熵的概念,香农把信源所含有的信息量称为信息熵,用于描述平均而言事件信息量的大小,所以在数学上,信息熵…