Конвертировать Python int в строку байтов с прямым порядком байтов - PullRequest
55 голосов
/ 11 мая 2009

У меня неотрицательный тип int, и я хотел бы эффективно преобразовать его в строку с прямым порядком байтов, содержащую те же данные. Например, int 1245427 (который равен 0x1300F3) должен привести к строке длиной 3, содержащей три символа, значения байтов которых равны 0x13, 0x00 и 0xf3.

Мои целые числа имеют шкалу из 35 (основание-10) цифр.

Как мне это сделать?

Ответы [ 8 ]

42 голосов
/ 11 мая 2009

Вы можете использовать модуль struct :

import struct
print struct.pack('>I', your_int)

'>I' - строка формата. > означает большой порядковый номер, а I означает беззнаковое целое. Проверьте документацию для большего количества символов формата.

40 голосов
/ 12 октября 2012

В Python 3.2+ вы можете использовать int.to_bytes :

Если вы не хотите указывать размер

>>> n = 1245427
>>> n.to_bytes((n.bit_length() + 7) // 8, 'big') or b'\0'
b'\x13\x00\xf3'

Если вы не возражаете, указав размер

>>> (1245427).to_bytes(3, byteorder='big')
b'\x13\x00\xf3'
13 голосов
/ 11 мая 2009

Это быстро и работает для маленьких и (произвольных) больших целых:

def Dump(n): 
  s = '%x' % n
  if len(s) & 1:
    s = '0' + s
  return s.decode('hex')
print repr(Dump(1245427))  #: '\x13\x00\xf3'
7 голосов
/ 15 февраля 2015

Совместимая версия Python 2/3 с одним исходным кодом, основанная на ответе @ pts :

#!/usr/bin/env python
import binascii

def int2bytes(i):
    hex_string = '%x' % i
    n = len(hex_string)
    return binascii.unhexlify(hex_string.zfill(n + (n & 1)))

print(int2bytes(1245427))
# -> b'\x13\x00\xf3'
7 голосов
/ 11 мая 2009

Вероятно, лучший способ - через встроенный модуль struct :

>>> import struct
>>> x = 1245427
>>> struct.pack('>BH', x >> 16, x & 0xFFFF)
'\x13\x00\xf3'
>>> struct.pack('>L', x)[1:]  # could do it this way too
'\x13\x00\xf3'

В качестве альтернативы - и я бы не рекомендовал это, потому что это подвержено ошибкам - вы можете сделать это "вручную", сдвигая и функция chr():

>>> x = 1245427
>>> chr((x >> 16) & 0xFF) + chr((x >> 8) & 0xFF) + chr(x & 0xFF)
'\x13\x00\xf3'

Из любопытства, почему вы хотите только три байта? Обычно вы упаковываете такое целое число в полные 32 бита (C unsigned long) и используете struct.pack('>L', 1245427), но пропускаете шаг [1:]?

6 голосов
/ 11 мая 2009
def tost(i):
  result = []
  while i:
    result.append(chr(i&0xFF))
    i >>= 8
  result.reverse()
  return ''.join(result)
3 голосов
/ 20 февраля 2012

Кратчайший путь, я думаю, следующий:

import struct
val = 0x11223344
val = struct.unpack("<I", struct.pack(">I", val))[0]
print "%08x" % val

Преобразует целое число в целое число с байтовым обменом.

3 голосов
/ 21 ноября 2009

Использование модуля bitstring :

>>> bitstring.BitArray(uint=1245427, length=24).bytes
'\x13\x00\xf3'

Обратите внимание, что для этого метода вам нужно указать длину в битах цепочки битов, которую вы создаете.

Внутренне это в значительной степени совпадает с ответом Алекса, но модуль имеет множество дополнительных функциональных возможностей, если вы хотите сделать больше с вашими данными.

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