以下表示从文件中提取的二进制图像(在字节之间插入空格以方便阅读)。文件以“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.
以二进制模式读取文件,就像您正在做的那样。这会生成一个
bytes
对象,该对象在 3.x 中与str
不同(在 2.x 中)。根据需要将字节解释为字节,以找出数据的一般结构。像以前一样对
字节
进行切片会产生另一个字节
;索引生成一个包含该单字节数值的int
(与以前不同) - 不需要ord
。当您确定了表示字符串的字节子集(为了方便起见,假设您已将其切分出来)时,请使用适当的编码将其转换为字符串:例如
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/