我正在研究一些包含(以及其他)文本的旧二进制文件。他们的文本经常出于原因使用自定义字符编码,我希望能够读取和重写它们。
在我看来,执行此操作的适当方法是使用标准编解码器库创建自定义编解码器。不幸的是,它的文档既庞大又完全不包含示例。Google出现了一些,但仅适用于python2,而我使用的是3。
我正在寻找有关如何使用编解码器库实现自定义字符编码的最小示例。
您要求的最低!
CodecInfo
这是将小写字母az顺序转换为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()
运行此打印
$ python codec_example.py 0123456 b'abcdefg'
有关界面的详细信息,请参见https://docs.python.org/3/library/codecs.html#codec- objectsCodec。特别是解码功能
Codec
…解码对象 输入 并返回一个元组(输出对象,消耗的长度)。
而编码功能
…编码对象 输入 并返回一个元组(输出对象,消耗的长度)。
注意,您还应该担心处理流,增量编码/解码以及错误处理。有关更完整的示例,请参考@ krs013提到的十六进制编解码器。
PS代替codec.decode,也可以使用codec.open(..., encoding='Reasons')。
codec.decode
codec.open(..., encoding='Reasons')