#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. в любом случае, важно то, что я получил число.