Декодирование числа с плавающей запятой двойной точности IEEE (8 байт)

Я декодирую файл формата AMF0. Данные, которые я ищу, представляют собой метку времени, закодированную в виде массива. [ЧЧ, ММ, СС].

Поскольку данные имеют формат AMF0, я могу найти начало данных, прочитав файл как байты, преобразовав каждый байт в шестнадцатеричный формат и найдя сигнал 08 00 00 00 03, массив длины 3.

Моя проблема в том, что я не знаю, как декодировать 8-байтовое целое число в каждом элементе массива. У меня есть данные в том же шестнадцатеричном формате, например:

08 00 00 00 03 *signals array length 3*
00 01 30 00 00 00 00 00 00 00 00 00 *signals integer*
00 01 31 00 00 00 00 00 00 00 00 00 *signals integer*
00 01 32 00 40 3C 00 00 00 00 00 00 *signals integer*
00 00 09 *signals object end*

Это должно быть расшифровано как [0, 0, 28] (если верить minerva).< br> Я пытался использовать struct.unpack, но все примеры, которые я вижу, относятся к 4-байтовым значениям (с прямым порядком байтов).


person jbzdarkid    schedule 13.06.2015    source источник


Ответы (2)


Спецификатор формата, который вы ищете, это ">9xd4xd4xd3x":

>>> import struct
>>> from binascii import unhexlify
>>> struct.unpack(">9xd4xd4xd3x", unhexlify("080000000300013000000000000000000000013100000000000000000000013200403C000000000000000009"))
(0.0, 0.0, 28.0)

Сломанный:

  1. >: формат с прямым порядком байтов
  2. 5x: 5-байтовый маркер начала массива + размер (игнорируется)
  3. 4x: 4-байтовый маркер начала элемента (игнорируется)
  4. d: 1 IEEE-754 с обратным порядком байтов double
  5. точки 2-3 для других 2-х элементов
  6. 3x: 3-байтовый маркер конца массива (игнорируется)

Точки 1. и 2. объединяются в 9x.

Как вы могли заметить, struct может только игнорировать лишние байты, но не проверять. Если вам нужна большая гибкость в формате ввода, вы можете использовать регулярное выражение, соответствующее маркерам начала/конца массива в нежадном режиме.

person Stefano Sanfilippo    schedule 13.06.2015

Для декодирования поплавков используйте struct-module:

>>> struct.unpack('>d','403C000000000000'.decode('hex'))[0]
28.0
person Daniel    schedule 13.06.2015