imewlconverter
imewlconverter copied to clipboard
百度输入法的个人词库导出只能是bin
首先非常肯定楼主的工具很好用,最近遇到个问题,我平时使用百度输入法的批量造词功能,批量创建个人词库。然后倒入到win10的输入法中使用,最近百度的新版本(好久不更新,最近又开始更新了),导出的词库只支持bin格式。所以楼主是否可以支持百度输入法的bin格式的转换 。非常感谢 百度输入法的个人词库导出只能是bin
现在的输入法也很鸡贼,之前都是可以导出TXT的,现在不行了
用21年版导出
用21年版导出
导出不了
现在有办法吗?
经过分析和查找,在网上找到了编码的算法,来源是分析他们浏览器的《某度base64魔改算法还原》。
文章里的分析和代码太乱了,用 Python 重写了一下,在这里贴一下解码的部分。Python 3.8 以上调用 decode_bin()
即可导出 UTF-16LE 的文本格式。
MASK = 0x2D382324
TABLE = b"qogjOuCRNkfil5p4SQ3LAmxGKZTdesvB6z_YPahMI9t80rJyHW1DEwFbc7nUVX2-"
DECODE_TABLE = bytes.maketrans(TABLE, bytes(range(64)))
def decode(data: bytes):
assert len(data) % 4 == 2
assert (base64_remainder := data[-2] - 65) in {0, 1, 2} and data[-1] == 0
data = data.translate(DECODE_TABLE)
transformed = bytearray()
for i in range(0, len(data) - 2, 4):
high_bits = data[i + 3]
transformed += bytes((
data[i] | (high_bits & 0b110000) << 2,
data[i + 1] | (high_bits & 0b1100) << 4,
data[i + 2] | (high_bits & 0b11) << 6,
))
if base64_remainder:
for i in range(3 - base64_remainder):
assert transformed.pop() == 0
result = bytearray()
for i in range(0, len(transformed) // 4 * 4, 4):
chunk = MASK ^ int.from_bytes(transformed[i : i + 4], byteorder="little")
chunk = (chunk & 0x1FFFFFFF) << 3 | chunk >> 29
result += chunk.to_bytes(4, byteorder="little")
if remainder := transformed[i + 4 :]:
chunk = MASK ^ int.from_bytes(remainder, byteorder="little")
result += chunk.to_bytes(4, byteorder="little")[: len(remainder)]
return result
def decode_bin(input_path: str, output_path: str):
assert input_path.endswith(".bin") and output_path.endswith(".txt")
with open(input_path, "rb") as f, open(output_path, "wb") as output:
output.write(b"\xff\xfe")
f.seek(1)
for line in f:
if data := line[1:-1]:
output.write(decode(data))
output.write(b"\n\0")
经过分析和查找,在网上找到了编码的算法,来源是分析他们浏览器的《某度base64魔改算法还原》。
文章里的分析和代码太乱了,用 Python 重写了一下,在这里贴一下解码的部分。Python 3.8 以上调用
decode_bin()
即可导出 UTF-16LE 的文本格式。MASK = 0x2D382324 TABLE = b"qogjOuCRNkfil5p4SQ3LAmxGKZTdesvB6z_YPahMI9t80rJyHW1DEwFbc7nUVX2-" DECODE_TABLE = bytes.maketrans(TABLE, bytes(range(64))) def decode(data: bytes): assert len(data) % 4 == 2 assert (base64_remainder := data[-2] - 65) in {0, 1, 2} and data[-1] == 0 data = data.translate(DECODE_TABLE) transformed = bytearray() for i in range(0, len(data) - 2, 4): high_bits = data[i + 3] transformed += bytes(( data[i] | (high_bits & 0b110000) << 2, data[i + 1] | (high_bits & 0b1100) << 4, data[i + 2] | (high_bits & 0b11) << 6, )) if base64_remainder: for i in range(3 - base64_remainder): assert transformed.pop() == 0 result = bytearray() for i in range(0, len(transformed) // 4 * 4, 4): chunk = MASK ^ int.from_bytes(transformed[i : i + 4], byteorder="little") chunk = (chunk & 0x1FFFFFFF) << 3 | chunk >> 29 result += chunk.to_bytes(4, byteorder="little") if remainder := transformed[i + 4 :]: chunk = MASK ^ int.from_bytes(remainder, byteorder="little") result += chunk.to_bytes(4, byteorder="little")[: len(remainder)] return result def decode_bin(input_path: str, output_path: str): assert input_path.endswith(".bin") and output_path.endswith(".txt") with open(input_path, "rb") as f, open(output_path, "wb") as output: output.write(b"\xff\xfe") f.seek(1) for line in f: if data := line[1:-1]: output.write(decode(data)) output.write(b"\n\0")
很棒,您有兴趣提 pr 吗
很棒,您有兴趣提 pr 吗
我没怎么写过 C# 也没有环境,对项目也不熟悉,如果你方便的话就转写一下吧。上面有别人上传的测试的文件,如果需要的话我也可以提供解码后的格式样本。
如果可以的话麻烦在提交信息里面加上一行:
Co-authored-by: stevenlele <[email protected]>
非常感谢各位大佬🙏
很棒,您有兴趣提 pr 吗
我没怎么写过 C# 也没有环境,对项目也不熟悉,如果你方便的话就转写一下吧。上面有别人上传的测试的文件,如果需要的话我也可以提供解码后的格式样本。
如果可以的话麻烦在提交信息里面加上一行:
Co-authored-by: stevenlele <[email protected]>
我已经提交了
https://github.com/studyzy/imewlconverter/blob/3012c564f282da6fafed721cd27599397013c244/src/ImeWlConverterCore/IME/BaiduPinyinBackup.cs#L31-L32
程序确实是按照 <cnword>
→ <enword>
→ <sysusrword>
的顺序导出的,应该不会出现乱序。
然后英文词的格式是:
API 0 0 4 1707932168
分隔符是 \t
,词频目测是 [3]
,至于 [1]
和 [2]
的意义不明确。我这里 [1]
有少量的 1、2、5 等值,[2]
都是 0。
https://github.com/studyzy/imewlconverter/blob/3012c564f282da6fafed721cd27599397013c244/src/ImeWlConverterCore/IME/BaiduPinyinBackup.cs#L31-L32
程序确实是按照
<cnword>
→<enword>
→<sysusrword>
的顺序导出的,应该不会出现乱序。
虽然我测试的也都是这个顺序,但也不能排除别的情况,这样写可以无视顺序。
然后英文词的格式是:
API 0 0 4 1707932168
分隔符是
\t
,词频目测是[3]
,至于[1]
和[2]
的意义不明确。我这里[1]
有少量的 1、2、5 等值,[2]
都是 0。
目前的程序对一种格式只能指定一种 CodeType,无法同时导入拼音和英文。