在ASCII字符串中查找二进制值

-1 投票
2 回答
853 浏览
提问于 2025-04-18 14:39

我有一个数据文件,打印出来后会显示一串字符,大概是这样的:

@ao��B��@�a��z�I{�@�M�C�cID ...等等

我还从这个数据文件中提取了一个二进制值,但我不确定它在文件中的具体位置。所以我可以用下面的方式读取数据:

  with open(self.filename, mode='rb') as data_file:
                self._file_contents = data_file.read()

我一直在尝试在这个代表文件的大字符串中搜索这个二进制值的起始位置。

[m.start() for m in re.finditer(binary, data_file._file_contents]

我尝试过把 binary 当作一个二进制字符串(比如 10011010),然后用 str(int(binary,2)) 把它转换成一个可以在文件中搜索的整数字符串值。 但是这些方法都没有成功,所以我开始怀疑自己的逻辑和思路。如果你知道怎么找到一个二进制值的索引,前提是你百分之百确定它在文件中,请告诉我你会怎么做。谢谢!

2 个回答

0

我在想有没有更直接的方法把它变成"\xff\xff\xff"这种形式?

当然可以。这种情况正是 struct 模块的用武之地:

>>> import struct
>>> struct.pack('<I', 4294967295)
'\xff\xff\xff\xff'
>>> struct.pack('<I', 1234567)
'\x87\xd6\x12\x00'

不过这里重要的是,你得知道你想要什么格式。上面的代码把每个数字当作小端格式的无符号32位C整数来处理,这是一种常见的把数字放进二进制数据里的格式,但并不是唯一的选择。

如果你想用十六进制(基数16)或二进制(基数2)来写这些值,而不是用十进制,当然可以;在Python看来,0b1001113 是一样的——都是数字13。所以:

>>> struct.pack('<I', 0b10011)
'\x13\x00\x00\x00'
>>> struct.pack('<I', 0xabcd)
'\xcd\xab\x00\x00'

不过,如果你只有在调用某个函数后才得到二进制格式的数字,那就别调用那个函数。

1
binary = "\x22"  # <- this is what binary should look like
[m.start() for m in re.finditer(binary, data_file._file_contents)]

如果你有一个整数值,比如说77,你可以用 binary = chr(77) 这个方法把它转换成二进制形式。

如果你有一个十六进制的值,比如 77=0x4d,你可以直接用 binary="\x4d" 来表示。

如果这个值大于0xff(也就是255),你就需要用到unichar,像这样 binary = unichr(257)。这时候你需要使用unicode字符串(257=0x0101),可以用 binary = u"\u0101" 或者 binary="\x01\x01" 来表示。

撰写回答