Подтвердить что ты не робот

Python: поиск/чтение двоичных данных

Я читаю двоичный файл (в этом случае jpg), и вам нужно найти некоторые значения в этом файле. Для тех, кого интересует, двоичный файл - это jpg, и я пытаюсь выбрать его размеры, ища двоичную структуру подробно здесь.

Мне нужно найти FFC0 в двоичных данных, пропустить некоторое количество байтов, а затем прочитать 4 байта (это должно дать мне размеры изображения).

Какой хороший способ поиска значения в двоичных данных? Есть ли эквивалент "найти" или что-то вроде re?

4b9b3361

Ответ 1

Фактически вы можете загрузить файл в строку и использовать

s.find('\xff\xc0')

Ответ 2

Модуль bitstring был разработан для этой цели. Для вашего случая следующий код (который я не тестировал) должен помочь проиллюстрировать:

from bitstring import ConstBitStream
# Can initialise from files, bytes, etc.
s = ConstBitStream(filename='your_file')
# Search to Start of Frame 0 code on byte boundary
found = s.find('0xffc0', bytealigned=True)
if found:
    print("Found start code at byte offset %d." % found[0])
    s0f0, length, bitdepth, height, width = s.readlist('hex:16, uint:16, 
                                                        uint:8, 2*uint:16')
    print("Width %d, Height %d" % (width, height))

Ответ 3

Модуль re работает как с строковыми , так и с двоичными данными (str в Python 2 и bytes в Python 3), поэтому вы можете использовать его, а также str.find для вашей задачи.

Ответ 4

Ну, очевидно, есть PIL Модуль Image имеет размер как атрибут. Если вы хотите получить размер именно так, как вы предлагаете, и без загрузки файла вам придется проходить его по очереди. Не самый приятный способ сделать это, но это сработает.

Ответ 5

Вместо того, чтобы читать весь файл в памяти, ища его, а затем записывая новый файл на диск, вы можете использовать для этого модуль mmap. mmap не будет хранить весь файл в памяти, и он допускает модификацию на месте.

#!/usr/bin/python

import mmap

with open("hugefile", "rw+b") as f:
    mm = mmap.mmap(f.fileno(), 0)
    print mm.find('\x00\x09\x03\x03')

Ответ 6

Метод find() должен использоваться только в том случае, если вам нужно знать позицию sub, если нет, вы можете использовать in, например:

with open("foo.bin", 'rb') as f:
    if b'\x00' in f.read():
        print('The file is binary!')
    else:
        print('The file is not binary!')

Ответ 7

python >= 3.2

import re

f = open("filename.jpg", "rb")
byte = f.read()
f.close()

matchObj = re.match( b'\xff\xd8.*\xff\xc0...(..)(..).*\xff\xd9', byte, re.MULTILINE|re.DOTALL)
if matchObj:
    # http://stackoverflow.com/questions/444591/convert-a-string-of-bytes-into-an-int-python
    print (int.from_bytes(matchObj.group(1), 'big')) # height
    print (int.from_bytes(matchObj.group(2), 'big')) # width

Ответ 8

В Python 3.x вы можете искать строку байта с помощью другой байтовой строки следующим образом:

>>> byte_array = b'this is a byte array\r\n\r\nXYZ\x80\x04\x95 \x00\x00\x00\x00\x00'
>>> byte_array.find('\r\n\r\n'.encode())
20
>>>