如何正确创建自定义文本编解码器?

时间:2016-08-04 21:38:42

标签: python python-3.x

我正在挖掘一些包含(除此之外)文本的旧二进制文件。他们的文本经常使用自定义字符编码作为原因,我希望能够阅读和重写它们。

在我看来,执行此操作的适当方法是使用standard codecs library创建自定义编解码器。不幸的是,它的文档既庞大又完全没有例子。谷歌出现了一些,但仅限于python2,我使用的是3.

我正在寻找一个如何使用编解码器库来实现自定义字符编码的最小示例。

2 个答案:

答案 0 :(得分:8)

您要求最少!

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

这里是一个将小写字母a-z顺序转换为0-25的示例。

import codecs
import string

# 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) -> bytes:
    # 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) -> str:
    # 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()

运行此打印

$ python codec_example.py
0123456
b'abcdefg'

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

  

...解码对象 input 并返回一个元组(输出对象,长度   消耗)。

而编码功能

  

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

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


P.S。除了使用codec.decode代替codec.open(..., encoding='Reasons')

答案 1 :(得分:1)

虽然在线文档肯定很少,但您可以通过查看the source code获取更多信息。文档字符串和注释非常清楚,父类(Codec,IncrementalEncoder等)的定义可以复制/粘贴到编解码器的开头(确保替换每个类中的object定义与您继承的类的名称)。同样值得查看我在评论中链接到的example如何汇编/注册它。

我已经和你在同一时间停留了一段时间,看看这个,祝你好运!如果我有几天的时间,我会在这里看到实际的实现和粘贴/链接。