Версия Python для Ruby's array.pack () и unpack ()? - PullRequest
1 голос
/ 22 мая 2019

В Ruby я мог бы легко упаковать массив, представляющий некоторую последовательность, в двоичную строку:

# for int
# "S*!" directive means format for 16-bit int, and using native endianess

# 16-bit int, so each digit was represented by two bytes. "\x01\x00" and "\x02\x00"
# here the native endianess is "little endian", so you should 
# look at it backwards, "\x01\x00" becomes 0001, and "\x02\x00" becomes 0002

"\x01\x00\x02\x00".unpack("S!*")
# [1, 2]


# for hex
# "H*" means every element in the array is a digit for the hexstream

["037fea0651b358c361de"].pack("H*")
# "\x03\x7F\xEA\x06Q\xB3X\xC3a\xDE"

API doc для pack и unpack .

Я не смог найти единого и эквивалентного способа преобразования последовательности в байты (или наоборот) в python.

Хотя struct предоставляет методы для упаковки в байтовые объекты, доступная строка формата не имеет опции для hexstream.

РЕДАКТИРОВАТЬ: Что мне действительно нужно, так это универсальность Ruby arr.pack и str.unpack, которая поддерживает множественное форматирование и контроль порядка байтов.

Ответы [ 3 ]

2 голосов
/ 22 мая 2019

для строки в диапазоне utf-8 это будет:

from binascii import unhexlify

strg = "464F4F"
unhexlify(strg).decode()  # FOO  (str)

если ваш контент только двоичный

strg = "037fea0651b358c361de"
unhexlify(strg) # b'\x03\x7f\xea\x06Q\xb3X\xc3a\xde'  (bytes)

также bytes.fromhex (как в ответ Дэвиса Херринга ), возможно, стоит проверить.

2 голосов
/ 22 мая 2019

struct делает только кодировки фиксированной ширины, которые соответствуют дампу памяти чего-то вроде структуры Си.Вы хотите bytes.fromhex или binascii.unhexlify, в зависимости от типа источника (который никогда не является списком).

После любого такого преобразования вы может использовать struct.unpack в байтовой строке, содержащей любое число «записей», соответствующих строке формата;каждый из них декодируется в элемент возвращаемого кортежа.Строка формата поддерживает обычные целочисленные размеры и порядки байтов;конечно, возможно построить формат динамически для таких вещей, как чтение матрицы, размеры которой выбираются во время выполнения:

mat=struct.unpack("%dd"%cols,buf)  # rows determined from len(buf)

Также возможно построить нижепамять array, если тип элемента примитив ;затем вы можете указать byteswap в качестве Алек, упомянутый .NumPy предлагает аналогичные услуги .

1 голос
/ 22 мая 2019

Попробуйте memoryview.cast, что позволяет изменить порядковый номер массива или байтового объекта.

Сохранение значений в виде массивов упрощает работу, так как вы можете использовать функцию byteswap.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...