Python распаковывает двоичные данные числовой длины 12

#python #struct #binaries

#python #struct #двоичные файлы

Вопрос:

У меня есть файл с большими конечными двоичными файлами. Есть два числовых поля. Первый имеет длину 8, а второй — 12. Как я могу распаковать два числа?

Я использую модуль Python struct (https://docs.python.org/2/library/struct.html ) и это работает для первого поля

 num1 = struct.unpack('>Q',payload[0:8])
 

но я не знаю, как я могу распаковать второе число. Если я рассматриваю его как char(12), то я получаю что-то вроде 'x00xe3ACx00x00x00x06x00x00x00x01' .

Спасибо.

Комментарии:

1. Это число, хранящееся в 12 байтах?

2. Извините за путаницу: необходимо распаковать 2 числа, одно имеет длину 8, а второе — длину 12. num1 Я могу распаковать, как указано выше. У меня возникли проблемы со вторым. Я ищу первый аргумент x для struct.unpack(x, полезная нагрузка [8:20]).

3. Мой плохой, я неправильно истолковал вопрос (и удалил неправильный комментарий, который я ввел из-за этого) Вы пробовали рассматривать его как три целых числа?: struct.unpack('>hhh', payload[8:20]) Что вы получите, если сделаете это?

4. ‘>hhh’ выдает struct.ошибка: для распаковки требуется строковый аргумент длиной 6. Когда я меняю его на ‘> хххххх’, тогда ‘ x00 xe3AC x00 x00 x00 x08 x00 x00 x00 x01’ становится (227, 16707, 0, 8, 0, 1). Но я думаю, что это должно быть одно число.

Ответ №1:

Я думаю, вам следует создать новую строку байтов для второго числа длиной 16, заполнить последние 12 байтов строкой байтов, содержащих ваш номер, а первые 4 — нулями.

Затем декодируйте байтовую строку с помощью unpack с форматированием >QQ , скажем numHI , numLO в переменные. Затем вы получаете окончательное число с этим: number = numHI * 2^64 numLO *. AFAIR целые числа в Python могут быть (почти) сколь угодно большими, так что у вас не будет проблем с переполнением. Это только приблизительная идея, пожалуйста, прокомментируйте, если у вас возникнут проблемы с написанием этого в реальном коде Python, затем я отредактирую свой ответ, чтобы предоставить дополнительную помощь.

*^ в данном случае является математической силой, поэтому, пожалуйста, используйте math.pow. В качестве альтернативы вы можете использовать сдвиг байта: number = numHI << 64 numLO .

Комментарии:

1. Я думаю, это сработало! Начиная со string=’x00 xe3ACx00x00 x00 x08 x00 x00 x00 x01′, я создал x= ‘0000’ string, затем я распаковываю numHI,numLO= unpack(‘>QQ’,x). Используя приведенную выше формулу, я получаю number= 6944656625227956935. К сожалению, я не могу прямо сейчас проверить, верно ли это число.

2. Я рад. Кроме того, я внес небольшое редактирование — вы можете использовать сдвиг байта вместо мощности 🙂

3. спасибо за вашу помощь. одна вещь. number = numHI * 2^64 numLO намного быстрее, чем number = numHI << 64 numLO

4. Это странно, я бы сказал, что двоичные операции выполняются быстрее :).

5. в общем, я согласен. хотя у моей машины были трудности с <<64. в любом случае, важно то, что я получил число.