2011-01-18 20 views
7

Quiero convertir un entero de 32 bytes (aunque podría necesitar otras longitudes) a un objeto bytes en python. ¿Hay una manera limpia y simple de hacer esto?Convierte n-byte int a bytes en python3

+0

¿Qué formato tiene el número entero actualmente? –

+5

entero de 32 bytes Eso es un montón de nu ... bytes. ¿Qué es exactamente lo que intentas lograr y qué pruebaste ya? –

+0

Tengo sha hashes en formato 0x ..., python está muy feliz convirtiéndolos en enteros, pero ¿cómo puedo obtener bytes? – Peter

Respuesta

3

Te estoy adivinando necesitan un entero de 32 bits, y big endian de arranque:

>>> from ctypes import c_uint32 
>>> l = c_uint32(0x12345678) 
>>> bytes(l) 
b'xV4\x12' 

Hay c_uint8, c_uint16 y c_uint64 también. Para ints más largos necesitas hacerlo manualmente, usando divmod (x, 256).

>>> def bytify(v): 
... v, r = divmod(v, 256) 
... yield r 
... if v == 0: 
...  raise StopIteration 
... for r in bytify(v): 
...  yield r 
... 
>>> [x for x in bytify(0x12345678)] 
[120, 86, 52, 18] 
>>> bytes(bytify(0x12345678)) 
b'xV4\x12 
>>> bytes(bytify(0x1234567890987654321)) 
b'!Ce\x87\t\x89gE#\x01!Ce\x87\t\x89gE#\x01' 
+0

No es necesario usar ctypes: 'bytes' se puede inicializar con una matriz de' int's en el rango (0, 256). – Tom

+0

@Tom: Al parecer, no leyó toda la respuesta. –

+0

Estimado @Lennart, comenzaste tu respuesta importando tipos. Continuó mostrando ctypes de varios tamaños. Luego proporcionaste una solución que no los usa (que personalmente creo que debería haber sido la primera solución), sin decirlo explícitamente. Solo pensé que era importante mencionar explícitamente el hecho, eso es todo. Tiene derecho a estar en desacuerdo, y no tiene que reformular su respuesta si no la ve, pero no es necesario lanzar acusaciones. Dije lo que dije porque creo que algunas personas pueden tener la impresión equivocada de que se necesitan ctypes y se desaniman con eso. – Tom

7

to_bytes (longitud, byteorder [firmado]) es todo lo que necesita a partir de 3,2. En este caso, algún identificador .to_bytes (4, 'grande') debería darle la cadena de bytes que necesita.

+0

>>> hash.to_bytes (32) ... Rastreo (llamada más reciente pasado): ... Archivo "", línea 1, en ... hash.to_bytes (32) ... AttributeError: el objeto 'builtin_function_or_method' no tiene ... atributo 'to_bytes' – Tom

+0

La próxima vez usaré un identificador diferente; 'hash' estaba destinado a ser el nombre de variable real o literal, no el incorporado. Olvidé que había una construcción así, mi mal. byteorder también se requiere ahora. – SilverbackNet

+0

Oh, estaba confundido, ahora está todo claro, ¡gracias! – Tom

2

Puede usar bytes("iterable") directamente. Donde cada valor en iterable será específico byte en bytes(). Ejemplo de codificación poco endian:

>>> var=0x12345678 
>>> var_tuple=((var)&0xff, (var>>8)&0xff, (var>>16)&0xff, (var>>24)&0xff) 
>>> bytes(var_tuple) 
b'xV4\x12' 
1

Suponga que tiene

var = 'і' # var is ukrainian і 

queremos obtener binaria de ella. Flujo es esto. valor/que es de cadena => bytes => int => binario

binary_var = '{:b}'.format(int.from_bytes(var.encode('utf-8'), byteorder='big')) 

Ahora binary_var es '1101000110010110'. Tipo es una cadena.

Ahora vuelve, desea obtener el valor Unicode de binario:

int_var = int(binary_var, 2) # here we get int value, int_var = 53654 

Ahora necesitamos convertir número entero de bytes. 'І' de Ucrania no va a encajar en 1 byte pero en 2. convertir a bytes reales bytes_var = B '\ xd1 \ x96'

bytes_var = int_var.to_bytes(2, byteorder='big') 

Finalmente Decodificamos nuestros bytes.

ukr_i = bytes_var.decode('utf-8') # urk_i = 'і'