Обработка байтов в Python существенно отличается в Python 2.7 и Python 3. В этой статье разъясняется, как преобразовать байты в целые числа в обеих версиях, с акцентом на важные различия.
Оглавление
- Python 2.7 и байтовые строки
- Преобразование байтов в целые числа в Python 2.7
- Python 3 и тип
bytes
- Преобразование байтов в целые числа в Python 3
Python 2.7 и байтовые строки
В Python 2.7 тип str
обрабатывает как текстовые, так и байтовые данные. Специального типа bytes
, как в Python 3, нет. Байтовые строки представляют собой последовательности символов, представляющих значения байтов. Важно помнить, что Python 2.7 официально устарел и не должен использоваться для новых проектов.
Преобразование байтов в целые числа в Python 2.7
Преобразование отдельных байтов в целые числа осуществляется с помощью функции ord()
:
byte_string = 'A' # Представляет байтовое значение 'A'
integer_value = ord(byte_string)
print(integer_value) # Вывод: 65
ord()
возвращает код точки Unicode, который совпадает с числовым значением байта для одиночных байтов. Для более длинных байтовых строк для преобразования в целые числа большего размера необходимы побитовые операции. В следующем примере предполагается порядок байтов little-endian:
byte_string = 'x01x02x03' # Пример байтовой строки (little-endian)
integer_value = 0
for byte in byte_string:
integer_value = (integer_value << 8) | ord(byte)
print(integer_value) # Вывод: 66051
Эта функция итеративно сдвигает целое число влево на 8 бит и применяет побитовое ИЛИ для включения каждого байта. Для порядка big-endian необходимо изменить порядок итерации.
Python 3 и тип bytes
Python 3 явно вводит тип bytes
, отделяя его от типа str
(текст Unicode). Объекты bytes
являются неизменяемыми последовательностями целых чисел в диапазоне от 0 до 255.
Преобразование байтов в целые числа в Python 3
Python 3 предлагает более чистый подход. Для одного байта:
byte_data = b'x41' # Обратите внимание на префикс 'b', указывающий на литерал байтов
integer_value = byte_data[0]
print(integer_value) # Вывод: 65
Непосредственный доступ к байту по индексу 0 дает целое значение. Для нескольких байтов используется int.from_bytes()
, указывающий порядок байтов (endianness):
byte_data = b'x01x02x03' # Пример little-endian
integer_value = int.from_bytes(byte_data, byteorder='little')
print(integer_value) # Вывод: 66051
byte_data = b'x01x02x03' # Пример big-endian
integer_value = int.from_bytes(byte_data, byteorder='big')
print(integer_value) # Вывод: 16909060
byteorder='little'
означает, что наименее значимый байт идёт первым, а byteorder='big'
— что наиболее значимый байт идёт первым. Всегда указывайте byteorder
для переносимости; в противном случае используется значение по умолчанию системы.