Если файлы не слишком большие (полностью помещаются в память), можно грузить в память, и матчить целиком.
Пример, если достаточно найти одно совпадение:
import re
pattern = b'\x80.A.+\x80.Z' # cmp reg8, 'A' ..... cmp reg8, 'Z'
with open("file.bin", 'rb') as f:
match = re.search(pattern, f.read())
if match:
print(hex(match.start()), match.group(0)) # выводим смещение от начала файла и найденное совпадение
else:
print('Nothing found')
Вывод:
0x2cb3b4 b'\x80\xf9A|\x05\x80\xf9Z'
Если нужно найти все совпадения:
with open("file.bin", 'rb') as f:
for match in re.finditer(pattern, f.read()):
print(hex(match.start()), match.group(0))
Вывод:
0x2cb3b4 b'\x80\xf9A|\x05\x80\xf9Z'
0x444184 b'\x80\xf9A|\x05\x80\xf9Z'
Тестировалось на файле размера порядка 10 МБ, нужные мне совпадения находит мгновенно.
Если файлы достаточно большие (несколько гигабайт), то придется читать файл по блокам. И все-таки нужно определиться, какой максимальный размер может занимать искомый блок данных, в зависимости от этого выбирать размер считываемого блока.
Нужно использовать два буфера, т.к. начало совпадения может оказаться внутри одного буфера, а конец внутри другого. На каждом этапе два соседних буфера складываются, поиск происходит внутри объединенного буфера.
Пример реализации:
block_size = 512*1024**2 # 512 мегабайт
block1 = b''
with open('file.bin', 'rb') as f:
while True:
block2 = f.read(block_size)
if not block2: # Достигнут конец файла
match = None
break
match = re.search(pattern, block1 + block2) # Не тестировалось на больших файлах, сцепление длинных байтовых строк в цикле может тормозить!
if match:
break
block1 = block2
if match:
print(hex(match.start()), match.group(0))
else:
print('Nothing found')