Поиск и отбор определенного количества байт в hex файле

Имеется файл hex (*.oub), нужно в нем найти все hex значения "01" и после этого символа скопировать в новый файл допустим 12 байт. И так до конца файла. Пример:

01 F9 F3 F9 F9 F9 F9 F9 F9 F9 F9 F9 F9 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 F9 F9 F9 01 F9 F3 F9 F9 F9 F9 F9 F9 F9 F9 F9 F9 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 F9 F9 F9 01 F9 F3 F9 F9 F9 F9 F9 F9 F9 F9 F9 F9 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 F9 F9 F9 01 F9 F3 F9 F9 F9 F9 F9 F9 F9 F9 F9 F9 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 F9 F9 F9 01 F9 F3 F9 F9 F9 F9 F9 F9 F9 F9 F9 F9 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 F9 F9 F9 01 F9 F3 F9 F9 F9 F9 F9 F9 F9 F9 F9 F9 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 F9 F9 F9 01 F9 F3 F9 F9 F9 F9 F9 F9 F9 F9 F9 F9 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 F9 F9 F9 01 F9 F3 F9 F9 F9 F9 F9 F9 F9 F9 F9 F9 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 F9 F9 F9 01 F9 F3 F9 F9 F9 F9 F9 F9 F9 F9 F9 F9 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 F9 F9 F9 01 F9 F3 F9 F9 F9 F9 F9 F9 F9 F9 F9 F9 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 F9 F9 F9 01 F9 F3 F9 F9 F9 F9 F9 F9 F9 F9 F9 F9 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 F9 F9 F9 01 F9 F3 F9 F9 F9 F9 F9 F9 F9 F9 F9 F9 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 F9 F9 F9

второй файл должен выглядеть так:

F9 F3 F9 F9 F9 F9 F9 F9 F9 F9 F9 F9 F9 F3 F9 F9 F9 F9 F9 F9 F9 F9 F9 F9 F9 F3 F9 F9 F9 F9 F9 F9 F9 F9 F9 F9 F9 F3 F9 F9 F9 F9 F9 F9 F9 F9 F9 F9 F9 F3 F9 F9 F9 F9 F9 F9 F9 F9 F9 F9 F9 F3 F9 F9 F9 F9 F9 F9 F9 F9 F9 F9 F9 F3 F9 F9 F9 F9 F9 F9 F9 F9 F9 F9 F9 F3 F9 F9 F9 F9 F9 F9 F9 F9 F9 F9 F9 F3 F9 F9 F9 F9 F9 F9 F9 F9 F9 F9 F9 F3 F9 F9 F9 F9 F9 F9 F9 F9 F9 F9 F9 F3 F9 F9 F9 F9 F9 F9 F9 F9 F9 F9 F9 F3 F9 F9 F9 F9 F9 F9 F9 F9 F9 F9

Помогите кто чем может, в пайтоне не силен....


Ответы (2 шт):

Автор решения: insolor

На примере бинарных файлов. К байтовым строкам можно применять байтовые регулярные выражения. Для вашего случая (байт 0x01, после которого нужно вытащить 12 байт) можно использовать такое регулярное выражение: br"\x01(.{12})" - т.е. буквально, байт с кодом 0x01, потом ровно 12 любых байт, заключаем их в скобки (группу), чтобы метод findall вытащил именно их без байта 0x01.

Будем считать, что диапазоны не пересекаются (в извлекаемых 12 байтах не встретится байт 0x01).

# Подготавливаем файл
with open("file1.bin", "wb") as file1:
    file1.write(bytes.fromhex("01 F9 F3 F9 F9 F9 F9 F9 F9 F9 F9 F9 F9 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 F9 F9 F9 01 F9 F3 F9 F9 F9 F9 F9 F9 F9 F9 F9 F9 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 F9 F9 F9 01 F9 F3 F9 F9 F9 F9 F9 F9 F9 F9 F9 F9 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 F9 F9 F9 01 F9 F3 F9 F9 F9 F9 F9 F9 F9 F9 F9 F9 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 F9 F9 F9 01 F9 F3 F9 F9 F9 F9 F9 F9 F9 F9 F9 F9 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 F9 F9 F9 01 F9 F3 F9 F9 F9 F9 F9 F9 F9 F9 F9 F9 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 F9 F9 F9 01 F9 F3 F9 F9 F9 F9 F9 F9 F9 F9 F9 F9 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 F9 F9 F9 01 F9 F3 F9 F9 F9 F9 F9 F9 F9 F9 F9 F9 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 F9 F9 F9 01 F9 F3 F9 F9 F9 F9 F9 F9 F9 F9 F9 F9 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 F9 F9 F9 01 F9 F3 F9 F9 F9 F9 F9 F9 F9 F9 F9 F9 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 F9 F9 F9 01 F9 F3 F9 F9 F9 F9 F9 F9 F9 F9 F9 F9 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 F9 F9 F9 01 F9 F3 F9 F9 F9 F9 F9 F9 F9 F9 F9 F9 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 F9 F9 F9"))


import re

with open("file1.bin", "rb") as file1:
    data = file1.read()
    findings = re.findall(br"\x01(.{12})", data)

with open("file2.bin", "wb") as file2:
    for item in findings:
        file2.write(item)

Результат

Тот же подход можно применить к текстовым hex файлам, только перед поиском hex значения нужно преобразовать в байты:

# Подготавливаем файл
with open("file1.hex", "w") as file1:
    file1.write("01 F9 F3 F9 F9 F9 F9 F9 F9 F9 F9 F9 F9 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 F9 F9 F9 01 F9 F3 F9 F9 F9 F9 F9 F9 F9 F9 F9 F9 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 F9 F9 F9 01 F9 F3 F9 F9 F9 F9 F9 F9 F9 F9 F9 F9 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 F9 F9 F9 01 F9 F3 F9 F9 F9 F9 F9 F9 F9 F9 F9 F9 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 F9 F9 F9 01 F9 F3 F9 F9 F9 F9 F9 F9 F9 F9 F9 F9 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 F9 F9 F9 01 F9 F3 F9 F9 F9 F9 F9 F9 F9 F9 F9 F9 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 F9 F9 F9 01 F9 F3 F9 F9 F9 F9 F9 F9 F9 F9 F9 F9 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 F9 F9 F9 01 F9 F3 F9 F9 F9 F9 F9 F9 F9 F9 F9 F9 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 F9 F9 F9 01 F9 F3 F9 F9 F9 F9 F9 F9 F9 F9 F9 F9 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 F9 F9 F9 01 F9 F3 F9 F9 F9 F9 F9 F9 F9 F9 F9 F9 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 F9 F9 F9 01 F9 F3 F9 F9 F9 F9 F9 F9 F9 F9 F9 F9 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 F9 F9 F9 01 F9 F3 F9 F9 F9 F9 F9 F9 F9 F9 F9 F9 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 F9 F9 F9")


import re
from binascii import hexlify

with open("file1.hex", "r") as file1:
    data = bytes.fromhex(file1.read())
    findings = re.findall(br"\x01(.{12})", data)

# Функция hexlify возвращает байты, поэтому открываем на запись в байтовом режиме
# (можно и в текстовом, но тогда от результата hexlify нужно будет вызывать .decode() )
with open("file2.hex", "wb") as file2:
    hex_data = b" ".join(hexlify(item, b" ") for item in findings)
    file2.write(hex_data)
→ Ссылка
Автор решения: CrazyElf

Если просто сама обработка, без чтения-записи файлов, то например так. Проверяю в конце, что совпало с тем, что должно получиться:

t1 = "01 F9 F3 F9 F9 F9 F9 F9 F9 F9 F9 F9 F9 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 F9 F9 F9 01 F9 F3 F9 F9 F9 F9 F9 F9 F9 F9 F9 F9 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 F9 F9 F9 01 F9 F3 F9 F9 F9 F9 F9 F9 F9 F9 F9 F9 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 F9 F9 F9 01 F9 F3 F9 F9 F9 F9 F9 F9 F9 F9 F9 F9 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 F9 F9 F9 01 F9 F3 F9 F9 F9 F9 F9 F9 F9 F9 F9 F9 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 F9 F9 F9 01 F9 F3 F9 F9 F9 F9 F9 F9 F9 F9 F9 F9 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 F9 F9 F9 01 F9 F3 F9 F9 F9 F9 F9 F9 F9 F9 F9 F9 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 F9 F9 F9 01 F9 F3 F9 F9 F9 F9 F9 F9 F9 F9 F9 F9 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 F9 F9 F9 01 F9 F3 F9 F9 F9 F9 F9 F9 F9 F9 F9 F9 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 F9 F9 F9 01 F9 F3 F9 F9 F9 F9 F9 F9 F9 F9 F9 F9 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 F9 F9 F9 01 F9 F3 F9 F9 F9 F9 F9 F9 F9 F9 F9 F9 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 F9 F9 F9 01 F9 F3 F9 F9 F9 F9 F9 F9 F9 F9 F9 F9 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 F9 F9 F9"
t2 = "F9 F3 F9 F9 F9 F9 F9 F9 F9 F9 F9 F9 F9 F3 F9 F9 F9 F9 F9 F9 F9 F9 F9 F9 F9 F3 F9 F9 F9 F9 F9 F9 F9 F9 F9 F9 F9 F3 F9 F9 F9 F9 F9 F9 F9 F9 F9 F9 F9 F3 F9 F9 F9 F9 F9 F9 F9 F9 F9 F9 F9 F3 F9 F9 F9 F9 F9 F9 F9 F9 F9 F9 F9 F3 F9 F9 F9 F9 F9 F9 F9 F9 F9 F9 F9 F3 F9 F9 F9 F9 F9 F9 F9 F9 F9 F9 F9 F3 F9 F9 F9 F9 F9 F9 F9 F9 F9 F9 F9 F3 F9 F9 F9 F9 F9 F9 F9 F9 F9 F9 F9 F3 F9 F9 F9 F9 F9 F9 F9 F9 F9 F9 F9 F3 F9 F9 F9 F9 F9 F9 F9 F9 F9 F9"
b1, b2 = map(bytes.fromhex, (t1, t2))

b3 = bytes()
n = 12
i = 0
while True:
    i = b1.find(0x01, i)
    if i < 0:
        break
    b3 += b1[i+1:i+1+n]
    i += 1+n
    
assert b3 == b2

Вариант для работы с файлами:

def find_bytes(where: bytes, what: int, blocksize: int) -> bytes:
    result = bytes()
    i = 0
    while True:
        i = where.find(what, i)
        if i < 0:
            break
        result += where[i+1:i+1+blocksize]
        i += 1+blocksize
    return result

with open("file_in.oub", "rb") as inp, open("file_out.oub", "wb") as out:
    out.write(find_bytes(inp.read(), 0x01, 12))
→ Ссылка