首页 > 其他分享 >搜狗输入法ng版导入细胞词库过程的简要分析

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

时间:2024-10-11 20:21:46浏览次数:10  
标签:搜狗 输入法 UTF 词库 dictionary BINARY 00 FILE

今天有点时间,对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 ]; then
    echo "用法: $0 <搜狗细胞词库路径>"
    exit 1
fi

BINARY_FILE="$1"

# 检查文件是否存在
if [ ! -f "$BINARY_FILE" ]; then
    echo "错误: 文件 '$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" ]]; then
    echo "$BINARY_FILE 似乎不是搜狗细胞词库,请检查。"
    exit 1
fi

# 读取指定偏移量区间的数据并将其转为 UTF-16LE 的字符串,再转换为 UTF-8
extract_section_utf16le() {
    local start=$1
    local 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=$1
    local end=$2
    local length=$((($end - $start + 1) / 2 * 2))
    
    # 读取字节,替换 0D 00 20 00 为 20 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 ]; then
        hex_count="${hex_count:0: -1}"
    fi

    # 去除尾部的 "00" 字节
    hex_count="${hex_count%%00*}"

    # 初始化词条数
    local entry_count=0
    for (( 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" ]; then
        echo "用户自定义词库"
    elif [ "$HEX_HEADER" == "401500004443530101" ]; then
        echo "官方词库"
    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-0x005(44 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_id
    cp "$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

 脚本运行截图:

 

标签:搜狗,输入法,UTF,词库,dictionary,BINARY,00,FILE
From: https://www.cnblogs.com/megusta/p/18459207

相关文章

  • 给输入法换个好看的皮肤吧
    好皮肤带来好心情!偶尔换个皮肤调整下心情也是不错的。本文就介绍一下去哪里找好皮肤。PS:不是所有输入法都有强大的皮肤功能,具体情况具体分析。‍官方的皮肤集市一般来说,大厂的输入法都会有皮肤功能,用户可以在搜索、下载和使用皮肤,也可以自己制作、上传皮肤(官方提供了皮肤编辑......
  • 你可能没听过的手机输入法技巧
    其实手机输入法真的很强‍手机输入法的自带功能比起电脑上的输入法,手机上的输入法有一些特有的功能。这里就以iPhone为例进行讲解,而安卓的话大部分情况也有类似的功能,这里就不一一进行评测了。‍快速移动光标当内容很多,想要移动光标到内容中间进行编辑的时候,可以直......
  • 你可能没听过的手机输入法技巧
    其实手机输入法真的很强‍手机输入法的自带功能比起电脑上的输入法,手机上的输入法有一些特有的功能。这里就以iPhone为例进行讲解,而安卓的话大部分情况也有类似的功能,这里就不一一进行评测了。‍快速移动光标当内容很多,想要移动光标到内容中间进行编辑的时候,可以直接在键......
  • 三千字长文:我知道的输入法技巧都在这了
    这些技巧能让你打字更快、更好。‍官方设置目前市面上有很多输入法软件,其中很多功能都是共有的,因为都是基础功能。因此,当选择了一款输入法好,可以先打开设置页面,好好地了解有什么功能。此外,还可以看输入法官网文档,例如搜狗输入法的文档就写的很详细:https://pinyin.sogou.com/fu......
  • 这可能是最全的输入法教程了
    输入法是我们离不开的软件,如果要评选用户最常使用的工具类应用,输入法一定名列前茅。由于输入法实在太常用了,我们往往会忽略它:我用自带的输入法就行,打几个字,用的着琢磨吗?实则不然,输入法软件有很多,也有很多进阶用法,这也是我写这系列教程的原因——让你打字速度更快,体验更好。‍......
  • 搜狗浏览器如何设置主页 在选项里面
    1.打开搜狗浏览器客户端,点击右上方三条横线,选择下方“选项”。 网址大全,我的最爱,空白页,自定义”四种选择,大家按需设置就好。 ......
  • 搜狗输入法AI汪仔关闭
    笔记本板载内存16G,要开两个虚拟机,虚拟机已经设为2G内存内存极度紧张下,研究进程优化。。。CentBrowser:300MTeams:320MAntimalwareServiceExecutable:193M,暂时不知道怎么关denfener搜狗输入法AI汪仔32位:122M搜狗输入法渲染进程32位:132M,进程好像关不掉,先不管了AI汪仔:D:\Prog......
  • mac输入法 cpu占用,解决mac使用输入法出现卡顿延迟
    1、介绍网上有各种方法,例如有touchbar的macbook关闭输入建议;定时重启“简体中文输入法”进程;关闭“显示器具有单独的空间”这些方法网上都能看到,有些人说能解决,有些人说还是卡,我试过了问题依然存在。网上还有一种思路就是换第三方输入法,一般推荐的都是搜狗输入法或者百度输入法......
  • WSL2+Ubuntu 22.04搭建Qt开发环境+中文输入法
    WSL2+Ubuntu22.04搭建Qt开发环境+中文输入法安装wsl略wsl更新wsl--updatewsl--versionwsl--status我的显示如下,如果你的版本不是wsl2需要改为wsl2:$wsl--update正在安装:适用于Linux的Windows子系统已安装适用于Linux的Windows子系统。$wsl......
  • 2024企业站群搜狗秒收录站群程序二开版--码山侠
    在SEO领域,站群策略是一种通过构建多个网站来提高搜索引擎排名和增加流量的方法。百度快排玩法,特别是针对搜狗搜索引擎的秒收录站群程序,是许多SEO从业者关注的焦点。以下是对这种策略的深度解析。站群策略的核心站群策略的核心在于构建多个网站,这些网站通常围绕同一主题或相关......