如何解码包含无效字节的字节对象,Python3

Jor*_*Lee 2 string encode decode python-3.x

在python2中,我可以整天生成以字符串格式表示的这些十六进制字节 '\x00\xaa\xff'

>>>’00'.decode('hex') + 'aa'.decode('hex') + 'ff'.decode('hex')
>>>'\x00\xaa\xff'
Run Code Online (Sandbox Code Playgroud)

同样,我可以在 python3 中做到这一点

>>> bytes.fromhex(’00’) + bytes.fromhex(‘aa’) + bytes.fromhex(‘ff’)
>>>b'\x00\xaa\xff'
Run Code Online (Sandbox Code Playgroud)

根据py2->py3这里的变化

Python 3.0 使用文本和(二进制)数据的概念,而不是 Unicode 字符串和 8 位字符串。所有文本都是Unicode;但是编码后的 Unicode 表示为二进制数据。

所以 Py2 版本的输出是一个字符串,而 Py3 版本的输出是字节类型的二进制数据

但我真的需要一个字符串版本!

根据上述文档:

由于 str 和 bytes 类型不能混合使用,您必须始终在它们之间进行显式转换。使用 str.encode() 从 str 转到 bytes,使用 bytes.decode() 从 bytes 转到 str。您还可以分别使用 bytes(s, encoding=...) 和 str(b, encoding=...) 。

好的,现在我必须解码这个字节类型的二进制数据......

>>> b'\x00\xaa\xff'.decode()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
UnicodeDecodeError: 'utf-8' codec can't decode byte 0xaa in position 1: invalid start byte
Run Code Online (Sandbox Code Playgroud)

哎呀!我不关心这里的 UTF-8 编码。

我可以得到一个虚拟的直通编解码器吗?

聚苯乙烯

为什么我需要'\x00\xaa\xff'而不是b'\x00\xaa\xff'

因为我正在接受这个字符串并将它传递给

一个用纯python编写的crc函数

crc16pure.crc16xmodem('\x00\xaa\xff')
Run Code Online (Sandbox Code Playgroud)

此函数期望遍历由字节组成的字符串。如果我给出函数,b'\x00\xaa\xff'那么它只是一个不能迭代的数字。

Jor*_*Lee 7

问题:我可以得到一个虚拟的直通编解码器吗?

答案:是的,使用 iso-8859-1

在python3中,以下不起作用

b'\x00\xaa\xff'.decode()
Run Code Online (Sandbox Code Playgroud)

默认编解码器 'utf-8' 无法解码字节 0xaa

只要你不关心字符集(比如,你看到什么字符print()),只想要一串 8 位字符,就像你在 python2 中得到的那样,然后使用 8 位编解码器iso-8859-1

b'\x00\xaa\xff'.decode('iso-8859-1')
Run Code Online (Sandbox Code Playgroud)