python - 如何像在 2.x 中那样从字节字符串中提取混合的二进制和 ascii 值?

标签 python python-3.7

以下表示从文件中提取的二进制图像(在字节之间插入空格以方便阅读)。文件以“rb”模式打开。

01 77 33 9F 41 42 43 44 00 11 11 11

在Python 2.7中,我将其作为字符串读取,然后使用ord()提取二进制值,然后我可以提取甚至搜索字符串中的特定文本值(例如字符4中的“ABCD”) -7)。二进制字节可以是 0-FF 之间的任何值。部分原因是我推迟了向 python 3 的转换。

我需要能够在 Python 3 中将字节字符串视为二进制和 ascii(而不是 unicode)值的混合。格式不固定,它由数据结构组成。例如,字节 2 中的 33 可能是一个记录长度,它告诉我下一条记录的开始位置。换句话说,我不能只是说我知道文本字符串始终位于位置 4。

我不编写该文件,我只是使用它,因此无法更改它。

我见过很多使用 b' 和其他东西来转换固定字符串的示例,但我需要一种方法来混合这些值,提取字节,2 字节到 8 字节值作为 16 位到 64 位单词,并在较大的字符串中提取/搜索 ASCII 字符串。

Python 3 中的字节/字符分离对于我的需要来说似乎有些不灵活。我确信有一种方法可以做到这一点,我只是还没有找到似乎涵盖这种情况的示例或已回答的问题。

这是一个简化的示例,我无法提供真实数据(它是专有的),但这说明了问题。真实的文件可能很短(<1K)或很大(>100K),包含多个不同大小的记录。

有没有一种简单、直接的方法来基本上复制我在 Python 2.7 中拥有的功能?

这是在 Windows 上。

谢谢

最佳答案

I need to be able, in Python 3, to treat a string of bytes as a mixture of binary and ascii (not unicode) values. The format is not fixed, it consists of data structures. For example, the 33 in byte 2 might be a record length that tells me where the start of the next record is. In other words, I can't just say that I know the text string is always in location 4.

  1. 以二进制模式读取文件,就像您正在做的那样。这会生成一个 bytes 对象,该对象在 3.x 中与 str 不同(在 2.x 中)。

  2. 根据需要将字节解释为字节,以找出数据的一般结构。像以前一样对字节进行切片会产生另一个字节;索引生成一个包含该单字节数值的 int(与以前不同) - 不需要 ord

  3. 当您确定了表示字符串的字节子集(为了方便起见,假设您已将其切分出来)时,请使用适当的编码将其转换为字符串:例如str(my_bytes, 'ascii')。请注意,ASCII 将处理字节值 0x80 到 0xFF;特别是对于二进制旧文件格式,您的数据很可能实际上类似于Latin-1:str(my_bytes, 'iso-8859-1')

search the string for a specific text value

您可以在文本或字节级别进行搜索 - bytes 对象支持 in 运算符,搜索 bytes 的子序列或单个整数值。在字符串转换之前或之后进行搜索是否更有意义取决于您正在做什么。

using b' and other things to convert fixed strings

b'' 只是 literal bytes 对象的语法。如果您请求从文件中读取的内容的repr,您将看到以下内容。在代码中的现有字符串文字上添加 b 前缀并不是真正“转换”任何内容,而是将其替换为您本来应该拥有的值。

2-byte to 8-byte values as 16-bit to 64-bit words

文档至少尽我所能地说明了这一点:

>>> help(int.from_bytes)
Help on built-in function from_bytes:

from_bytes(...) method of builtins.type instance
    int.from_bytes(bytes, byteorder, *, signed=False) -> int

    Return the integer represented by the given array of bytes.

    The bytes argument must be a bytes-like object (e.g. bytes or bytearray).

    The byteorder argument determines the byte order used to represent the
    integer.  If byteorder is 'big', the most significant byte is at the
    beginning of the byte array.  If byteorder is 'little', the most
    significant byte is at the end of the byte array.  To request the native
    byte order of the host system, use `sys.byteorder' as the byte order value.

    The signed keyword-only argument indicates whether two's complement is
    used to represent the integer.

关于python - 如何像在 2.x 中那样从字节字符串中提取混合的二进制和 ascii 值?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57245883/

相关文章:

python - 将格式化为 csv 文件的单个字符串转换为 pandas 数据框

python - 如何在python中调整直方图上的字体大小

python - Tweepy 不会安装在 python 3.7 上;显示 "syntax error"

python-3.x - python3.7 pip install mysqlclient 失败,错误为 'Building wheel for mysqlclient (setup.py) ... error'

python - SQL语句中的字符串转义

python - 创建 python 绑定(bind)时出错

python - 从 Tornado 异步调用函数

python - 使用切换按钮

python - 安装mysql后Windows cmd无法识别python或pip

python - 从带有变量的字典中请求值