libreria - struct python 3
Convierta un Python int en una cadena de bytes big-endian (8)
Tengo un int no negativo y me gustaría convertirlo eficientemente en una cadena de big-endian que contenga los mismos datos. Por ejemplo, int 1245427 (que es 0x1300F3) debería dar como resultado una cadena de longitud 3 que contiene tres caracteres cuyos valores de byte son 0x13, 0x00 y 0xf3.
Mis entradas están en la escala de 35 (base-10) dígitos.
¿Cómo hago esto?
En Python 3.2+, puede usar int.to_bytes :
Si no quieres especificar el tamaño
>>> n = 1245427
>>> n.to_bytes((n.bit_length() + 7) // 8, ''big'') or b''/0''
b''/x13/x00/xf3''
Si no te importa especificar el tamaño
>>> (1245427).to_bytes(3, byteorder=''big'')
b''/x13/x00/xf3''
Esto es rápido y funciona para pequeñas y grandes (arbitrarias) entradas grandes:
def Dump(n):
s = ''%x'' % n
if len(s) & 1:
s = ''0'' + s
return s.decode(''hex'')
print repr(Dump(1245427)) #: ''/x13/x00/xf3''
La forma más corta, creo, es la siguiente:
import struct
val = 0x11223344
val = struct.unpack("<I", struct.pack(">I", val))[0]
print "%08x" % val
Esto convierte un entero en un entero intercambiado por bytes.
Probablemente la mejor manera sea a través del struct incorporado:
>>> 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''
Alternativamente, y normalmente no lo recomendaría, porque es propenso a errores, puede hacerlo "manualmente" cambiando y la función chr()
:
>>> x = 1245427
>>> chr((x >> 16) & 0xFF) + chr((x >> 8) & 0xFF) + chr(x & 0xFF)
''/x13/x00/xf3''
Por curiosidad, ¿por qué solo quieres tres bytes? Por lo general, debe empaquetar un entero de este tipo en un total de 32 bits (un C unsigned long
), y usar struct.pack(''>L'', 1245427)
pero omita el paso [1:]
?
Puedes usar el módulo struct :
import struct
print struct.pack(''>I'', your_int)
''>I''
es una cadena de formato. >
significa big endian y I
significa unsigned int. Consulte la documentación para obtener más caracteres de formato.
Usando el módulo de bitstring :
>>> bitstring.BitArray(uint=1245427, length=24).bytes
''/x13/x00/xf3''
Sin embargo, tenga en cuenta que para este método necesita especificar la longitud en bits de la cadena de bits que está creando.
Internamente, esto es más o menos lo mismo que la respuesta de Alex, pero el módulo tiene muchas funcionalidades adicionales disponibles si desea hacer más con sus datos.
Versión compatible Single-source Python 2/3 basada en la respuesta de @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''
def tost(i):
result = []
while i:
result.append(chr(i&0xFF))
i >>= 8
result.reverse()
return ''''.join(result)