Таблица 7.5. Спецификаторы порядка байтов
Спецификатор | Порядок байтов |
---|
< | Прямой порядок |
> | Обратный порядок |
Таблица 7.6. Спецификаторы формата
Спецификатор | Описание | Количество байтов |
---|
x | Пропустить байт | 1 |
b | Знаковый байт | 1 |
B | Беззнаковый байт | 1 |
h | Знаковое короткое целое число | 2 |
H | Беззнаковое короткое целое число | 2 |
i | Знаковое целое число | 4 |
I | Беззнаковое целое число | 4 |
l | Знаковое длинное целое число | 4 |
L | Беззнаковое длинное целое число | 4 |
Q | Беззнаковое очень длинное целое число | 8 |
f | Число с плавающей точкой | 4 |
d | Число с плавающей точкой двойной точности | 8 |
p | Счетчик и символы | 1 + count |
s | Символы | count |
Спецификаторы типа следуют за символом, указывающим порядок байтов. Перед любым спецификатором может следовать число, которое указывает количество; запись 5B аналогична записи BBBBB.
Вы можете использовать префикс счетчика вместо конструкции >LL:
>>>> struct.unpack('>2L', data[16:24])
>(154, 141)
Мы использовали разбиение data[16:24], чтобы получить непосредственно интересующие нас байты. Мы также могли добавить спецификатор x, чтобы пропустить неинтересные части:
>>>> struct.unpack('>16x2L6x', data)
>(154, 141)
Эта строка означает:
• использовать формат с обратным порядком байтов (>);
• пропустить 16 байт (16x);
• прочесть 8 байт — два беззнаковых длинных целых числа (2L);
• пропустить последние 6 байт (6x).
Другие инструменты для работы с бинарными данными
Некоторые сторонние пакеты с открытым исходным кодом часто предлагают следующие более декларативные способы определения и извлечения бинарных данных:
• bitstring (http://bit.ly/py-bitstring);
• construct (http://bit.ly/py-construct);
• hachoir (http://bit.ly/hachoir-pkg);
• binio (http://spika.net/py/binio/).
В приложении Г содержатся инструкции о том, как загрузить и установить внешние пакеты вроде этих. Для следующего примера вам нужно установить пакет construct. Вот все, что вам необходимо сделать:
>$ pip install construct
Вот так можно извлечь измерения PNG из нашей строки байтов data с помощью пакета construct:
>>>> from construct import Struct, Magic, UBInt32, Const, String
>>>> # адаптировано из кода по адресу https://github.com/construct
>>>> fmt = Struct('png',
>…·····Magic(b'\x89PNG\r\n\x1a\n'),
>…·····UBInt32('length'),
>…·····Const(String('type', 4), b'IHDR'),
>…·····UBInt32('width'),
>…·····UBInt32('height')
>…·····)
>>>> data = b'\x89PNG\r\n\x1a\n\x00\x00\x00\rIHDR' + \
>…·····b'\x00\x00\x00\x9a\x00\x00\x00\x8d\x08\x02\x00\x00\x00\xc0'
>>>> result = fmt.parse(data)
>>>> print(result)
>Container:
>····length = 13
>····type = b'IHDR'
>····width = 154
>····height = 141
>>>> print(result.width, result.height)
>154, 141