Структура.распаковка и длина байтового объекта

#python

#python

Вопрос:

У меня есть следующий код (данные — это байтовый объект):

     v = sum(struct.unpack('!%sH' % int(len(data)/2), data))
  

Часть, которая меня смущает, — это %sH в строке формата и % int(len(data)/2

Как именно работает эта часть кода? Какова длина байтового объекта? И из чего именно это складывается?

Ответ №1:

Предполагая, что у вас есть строка байтов data , такая как:

 >>> data = b'x01x02x03x04'
>>> data
'x01x02x03x04'
  

Длина — это количество байтов (или символов) в байтовой строке:

 >>> len(data)
4
  

Итак, это эквивалентно вашему коду:

 >>> import struct
>>> struct.unpack('!2H', data)
(258, 772)
  

Это указывает struct модулю использовать следующие символы формата:

  • ! — использовать сетевой режим (big endian)
  • 2H — распакуйте 2 x неподписанных коротких файла (по 16 бит каждый)

И он возвращает два целых числа, которые соответствуют предоставленным нами данным:

 >>> 'x' % 258
'0102'
>>> 'x' % 772
'0304'
  

Все, что делает ваш код, это автоматически вычисляет количество unsigned shorts на лету

 >>> struct.unpack('!%sH' % int(len(data)/2), data)
(258, 772)
  

Но в int преобразовании нет необходимости, и на самом деле не следует использовать %s заполнитель, поскольку он предназначен для замены строки:

 >>> struct.unpack('!%dH' % (len(data)/2), data)
(258, 772)
  

Таким образом, unpack возвращает два целых числа, относящиеся к распаковке 2 unsigned shorts из байта данных str. Затем Sum возвращает сумму этих:

 >>> sum(struct.unpack('!%dH' % (len(data)/2), data))
1030
  

Ответ №2:

Как работает ваш код:

  • Вы интерпретируете байтовую структуру data
    • struct.unpack использует строку для определения байтового формата данных, которые вы хотите интерпретировать
    • Заданный формат stuct.unpack возвращает итерацию интерпретируемых данных.
  • Затем вы суммируете interable.

Форматирование байтов

Чтобы интерпретировать передаваемые вами данные, вы создаете строку, сообщающую Python, в какой форме data они представлены. В частности, %sH часть представляет собой сокращенную комбинацию для этого количества беззнаковых сокращений, которые затем вы форматируете, чтобы указать точное количество, которое unsigned short вы хотите.

В этом случае число равно:

 int(len(data) / 2)
  

потому что unsigned short обычно имеет ширину 2 байта.