我正在翻阅一些包含文本的旧二进制文件.由于某些原因,他们的文本经常使用自定义字符编码,我希望能够阅读和重写它们.

在我看来,实现这一点的适当方法是使用standard codecs library创建自定义编解码器.不幸的是,它的文档既庞大又完全没有实例.谷歌出现了一些,但只针对python2,而我使用的是3.

我正在寻找一个如何使用编解码器库实现自定义字符编码的简单示例.

推荐答案

你要的是最低限度的!

  • 编写一个编码函数和一个解码函数.
  • 编写一个"搜索函数",返回由上述编码器和解码器构造的CodecInfo个对象.
  • 使用codec.register注册一个返回上述CodecInfo对象的函数.

下面是一个按顺序将小写字母a-z转换为0-25的示例.

import codecs
import string

from typing import Tuple

# prepare map from numbers to letters
_encode_table = {str(number): bytes(letter, 'ascii') for number, letter in enumerate(string.ascii_lowercase)}

# prepare inverse map
_decode_table = {ord(v): k for k, v in _encode_table.items()}


def custom_encode(text: str) -> Tuple[bytes, int]:
    # example encoder that converts ints to letters
    # see https://docs.python.org/3/library/codecs.html#codecs.Codec.encode
    return b''.join(_encode_table[x] for x in text), len(text)


def custom_decode(binary: bytes) -> Tuple[str, int]:
    # example decoder that converts letters to ints
    # see https://docs.python.org/3/library/codecs.html#codecs.Codec.decode
    return ''.join(_decode_table[x] for x in binary), len(binary)


def custom_search_function(encoding_name):
    return codecs.CodecInfo(custom_encode, custom_decode, name='Reasons')


def main():

    # register your custom codec
    # note that CodecInfo.name is used later
    codecs.register(custom_search_function)

    binary = b'abcdefg'
    # decode letters to numbers
    text = codecs.decode(binary, encoding='Reasons')
    print(text)
    # encode numbers to letters
    binary2 = codecs.encode(text, encoding='Reasons')
    print(binary2)
    # encode(decode(...)) should be an identity function
    assert binary == binary2

if __name__ == '__main__':
    main()

运行这个 fingerprint

$ python codec_example.py
0123456
b'abcdefg'

有关Codec界面的详细信息,请参见https://docs.python.org/3/library/codecs.html#codec-objects.尤其是解码功能

... 解码对象input并返回元组(输出对象,长度

而编码功能

... 对对象input进行编码并返回一个元组(输出对象,消耗的长度).

请注意,您还应该担心处理流、增量编码/解码以及错误处理.有关更完整的示例,请参阅@krs013提到的hexlify codec.


另外,你也可以用codec.open(..., encoding='Reasons')代替codec.decode.

Python-3.x相关问答推荐

类型的可变性对变量的作用域有影响吗?

这是重命名极地df列的最好方式吗?

在BaseHTTPRequestHandler中填充和返回列表

Pandas 根据条件增加Dataframe列

估计列表中连续对的数量

python 3.10.5 中可能存在的错误. id 函数工作不明确

通过点和线计算CV2 Homography

通过附加/包含多个列表来创建 nDimensional 列表

使用 from re findall 组合连续匹配并分离非连续匹配

集合操作:应该只适用于集合,但适用于 dict_keys?

Tkinter IntVar 返回 PY_VAR0 而不是值

多个返回函数的列表理解?

UnicodeDecodeError:utf-8编解码器无法解码位置 1 的字节 0x8b:无效的起始字节,同时读取Pandas中的 csv 文件

sys.stdin.readline() 和 input():读取输入行时哪个更快,为什么?

使用逗号时,除了处理程序中的语法无效

pip install dryscrape 失败并显示错误:[Errno 2] 没有这样的文件或目录:'src/webkit_server'?

如何在继承的数据类中创建可选字段?

python - Pandas - Dataframe.set_index - 如何保留旧的索引列

注册 Celery 基于类的任务

在 PyCharm 中配置解释器:请使用不同的 SDK 名称