Как перевести число в байты python
Перейти к содержимому

Как перевести число в байты python

  • автор:

Байты (bytes и bytearray)

Python 3 логотип

Байтовые строки в Python — что это такое и с чем это едят? Байтовые строки очень похожи на обычные строки, но с некоторыми отличиями. Попробуем выяснить, с какими.

Что такое байты? Байт — минимальная единица хранения и обработки цифровой информации. Последовательность байт представляет собой какую-либо информацию (текст, картинку, мелодию. ).

Создаём байтовую строку:

   
   Что делать с байтами? Хотя байтовые строки поддерживают практически все строковые методы, с ними мало что нужно делать. Обычно их надо записать в файл / прочесть из файла и преобразовать во что-либо другое (конечно, если очень хочется, то можно и распечатать). Для преобразования в строку используется метод decode:
 Bytearray в python - массив байт. От типа bytes отличается только тем, что является изменяемым. Про него, в общем-то, больше рассказать нечего.

Для вставки кода на Python в комментарий заключайте его в теги

Python, байты и числа в integer

Осваиваю постепенно пайтон, пишу программу для общения с AVR контроллером через блютуз. Из сокета я получаю данные в виде строки байт такого вида b'\xb1\xaa\xab\xac\xad\xae\xaf' . Так как я пишу свой протокол и работаю с разными типами данных (отправляю их с МК не в символьном виде), разбиваю строку на части, к примеру: b'\xb1' , b\xaa\xab' и b\xac\xad\xae\xaf' , то есть на однобайтовый int, двухбайтовый int и четырёхбайтовый int, с чем проблем не возникает. Главная задача - преобразовать эти байтовые последовательности в исходные числа. Однобайтовый int вполне получается преобразовать так:

In [64]: line = b'\t\xaa\xab\xac\xad\xae\xaf' In [65]: line [0] Out[65]: 9 In [72]: a = line [0] In [73]: a Out[73]: 9 In [74]: a += 1 In [75]: a Out[75]: 10 

Но вот метод преобразования в число двух и более бай мне неведом. В результате поиска больше запутался. И так, вопрос: как имея в исходных данных байтовые строки вида b\xaa\xab' и b\xac\xad\xae\xaf' привести их к целочисленному типу данных?

Отслеживать
52.4k 11 11 золотых знаков 110 110 серебряных знаков 312 312 бронзовых знаков
задан 24 ноя 2016 в 13:21
Алексей Симаков Алексей Симаков
141 1 1 золотой знак 3 3 серебряных знака 13 13 бронзовых знаков
какая версия pythonа?
24 ноя 2016 в 13:48
Spyder, Python 3.5
24 ноя 2016 в 13:52

2 ответа 2

Сортировка: Сброс на вариант по умолчанию

Чтобы конвертировать байты в целое число в Питоне 3 в независимости от числа байт:

>>> int.from_bytes(b'\xb1', 'big') 177 >>> int.from_bytes(b'\xaa\xab', 'big') 43691 >>> int.from_bytes(b'\xac\xad\xae\xaf', 'big') 2897063599 >>> int.from_bytes(b'\xac\xad\xae\xaf', 'big', signed=True) -1397903697 >>> int.from_bytes(b'\xac\xad\xae\xaf', 'little', signed=True) -1347506772 >>> int.from_bytes(b'\xac\xad\xae\xaf', 'little') 2947460524 

Если много однотипных данных, можно array.array , numpy.array использовать для экономии памяти и быстроты работы векторных операций.

Преобразование шестнадцатеричных строк в байты в Python

Для тех, кто предпочитает сразу перейти к сути, примените метод bytes.fromhex() в Python:

Скопировать код

hex_str = "68656c6f" bytes_obj = bytes.fromhex(hex_str) print(bytes_obj) # b'hello'

Обратите внимание: перед преобразованием удалите префикс '0x' и пробелы.

Преобразование в зависимости от версии Python

В Python 3 конвертация шестнадцатеричной строки в байты легко выполняется с помощью bytes.fromhex() :

Скопировать код

hex_string = "4A6F7921" bytes_result = bytes.fromhex(hex_string)

Пользователям Python 2.7 необходимо действовать по-другому:

Скопировать код

hex_string = "4A6F7921" bytes_result = hex_string.decode("hex")

Обработка нежелательных символов

Если шестнадцатеричная строка содержит пробелы или префикс 0x , их нужно удалить:

Скопировать код

dirty_hex_string = "0x4a 6f 79 21" clean_hex_string = dirty_hex_string.replace("0x", "").replace(" ", "") bytes_result = bytes.fromhex(clean_hex_string) # теперь строка готова к преобразованию

Визуализация

Шестнадцатеричные строки можно рассматривать как элементы конструктора, которые необходимо собрать в трехмерный объект:

Скопировать код

В разобранном виде (шестнадцатеричная): "48656c6c6f"

Преобразуем в байты:

Скопировать код

puzzle_pieces = bytes.fromhex("48656c6c6f")

В результате получаем:

Скопировать код

В разобранном виде (шестнадцатеричная): "48656c6c6f" ➡️ �� ➡️ Собранная мебель (байты): b'Hello'

Альтернативные методы преобразования

Применение binascii для получения байтов

Модуль binascii облегчает преобразование шестнадцатеричных чисел в байты и целочисленные значения:

Скопировать код

import binascii hex_string = "01FF" bytes_result = binascii.unhexlify(hex_string) # Преобразование в целое число int_value = int(hex_string, 16) # Результатом будет число 511.

Числовые преобразования с использованием struct.unpack

Преобразование байт в числа проводится с помощью struct.unpack , что дает возможность работать с данными на более низком уровне:

Скопировать код

import struct bytes_data = b'\x00\x01' number = struct.unpack('!H', bytes_data)[0]

Не забывайте указывать порядок следования байтов (big-endian или little-endian).

Воспользоваться модулем codecs для декодирования байтов

codecs — это ещё один способ декодирования шестнадцатеричных строк в байты:

Скопировать код

import codecs hex_string = "deadbeef" bytes_result = codecs.decode(hex_string, "hex")

Продвинутое преобразование и сложные случаи

При работе с большим объемом данных важен учет производительности

При обработке больших данных не забывайте об оптимизации производительности и обходе потенциальных узких мест.

Понимание типов данных в struct

Контроль типов и размеров данных становится важным при использовании struct.unpack .

Изменение данных после преобразования

bytearray.fromhex() идеален для модификации данных после преобразования:

Конвертация между байтами и строками#

Избежать работы с байтами нельзя. Например, при работе с сетью или файловой системой, чаще всего, результат возвращается в байтах.

Соответственно, надо знать, как выполнять преобразование байтов в строку и наоборот. Для этого и нужна кодировка.

Кодировку можно представлять как ключ шифрования, который указывает:

  • как «зашифровать» строку в байты (str -> bytes). Используется метод encode (похож на encrypt)
  • как «расшифровать» байты в строку (bytes -> str). Используется метод decode (похож на decrypt)

Эта аналогия позволяет понять, что преобразования строка-байты и байты-строка должны использовать одинаковую кодировку.

encode, decode#

Для преобразования строки в байты используется метод encode:

In [1]: hi = 'привет' In [2]: hi.encode('utf-8') Out[2]: b'\xd0\xbf\xd1\x80\xd0\xb8\xd0\xb2\xd0\xb5\xd1\x82' In [3]: hi_bytes = hi.encode('utf-8') 

Чтобы получить строку из байт, используется метод decode:

In [4]: hi_bytes Out[4]: b'\xd0\xbf\xd1\x80\xd0\xb8\xd0\xb2\xd0\xb5\xd1\x82' In [5]: hi_bytes.decode('utf-8') Out[5]: 'привет' 

str.encode, bytes.decode#

Метод encode есть также в классе str (как и другие методы работы со строками):

In [6]: hi Out[6]: 'привет' In [7]: str.encode(hi, encoding='utf-8') Out[7]: b'\xd0\xbf\xd1\x80\xd0\xb8\xd0\xb2\xd0\xb5\xd1\x82' 

А метод decode есть у класса bytes (как и другие методы):

In [8]: hi_bytes Out[8]: b'\xd0\xbf\xd1\x80\xd0\xb8\xd0\xb2\xd0\xb5\xd1\x82' In [9]: bytes.decode(hi_bytes, encoding='utf-8') Out[9]: 'привет' 

В этих методах кодировка может указываться как ключевой аргумент (примеры выше) или как позиционный:

In [10]: hi_bytes Out[10]: b'\xd0\xbf\xd1\x80\xd0\xb8\xd0\xb2\xd0\xb5\xd1\x82' In [11]: bytes.decode(hi_bytes, 'utf-8') Out[11]: 'привет' 

Как работать с Юникодом и байтами#

Есть очень простое правило, придерживаясь которого, можно избежать, как минимум, части проблем. Оно называется «Юникод-сэндвич»:

  • байты, которые программа считывает, надо как можно раньше преобразовать в Юникод (строку)
  • внутри программы работать с Юникод
  • Юникод надо преобразовать в байты как можно позже, перед передачей

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *