2010-08-12 15 views
26

Tengo una lista de valores ascii enteros que necesito transformar en una cadena (binaria) para usarla como clave para una operación de cifrado. (Estoy volviendo a implementar el código de Java cripto en python)Lista de enteros en cadena (matriz de bytes) - python

Esto funciona (suponiendo una clave de 8 bytes):

key = struct.pack('BBBBBBBB', 17, 24, 121, 1, 12, 222, 34, 76) 

Sin embargo, yo preferiría no tener la longitud de la clave y desempaquetar() parámetro lista codificada

¿Cómo podría implementar esto correctamente, dada una lista inicial de números enteros?

Gracias!

+0

¿Por qué necesita una cadena 'binaria'? – relet

Respuesta

37

me gusta mucho más el módulo array al módulo struct para este tipo de tareas (que implican secuencias de homogéneos valores):

>>> import array 
>>> array.array('B', [17, 24, 121, 1, 12, 222, 34, 76]).tostring() 
'\x11\x18y\x01\x0c\xde"L' 

sin len llamada, sin manipulación de cadenas es necesario, etc - rápida , simple, directo, ¿por qué preferir otro enfoque?

+1

Esto tiene más sentido para mí, lógicamente. ¡Gracias por el consejo! – mikewaters

8
struct.pack('B' * len(integers), *integers) 

*sequence significa "secuencia de desempaquetado" - o mejor dicho, "cuando se llama a f(..., *args ,...), dejar que args = sequence".

+0

Interesante; Debería haberme dado cuenta de que podía usar la multiplicación en la cuerda, pero no sabía sobre la 'secuencia de desembalaje'. ¡Gracias! – mikewaters

49

Para Python 2.6 y versiones posteriores, si se trata de bytes a continuación, un bytearray es la elección más obvia:

>>> str(bytearray([17, 24, 121, 1, 12, 222, 34, 76])) 
'\x11\x18y\x01\x0c\xde"L' 

Para mí esto es aún más directa que la respuesta de Alex Martelli - todavía no hay manipulación de cadenas o len llamada ¡pero ahora ni siquiera necesitas importar nada!

+2

Para aquellos que se preguntan, la respuesta de Alex Martelli parece funcionar más rápido, al menos con mis puntos de referencia en Python 2.7.7. Para 10.000 carreras, es 12 ms para su respuesta frente a 18 ms para esto; estos números son repetibles con poca variación. De acuerdo, no es una gran ganancia, solo cuando se trabaja con una gran cantidad de datos. Dicho esto, esta respuesta es más rápida para mí en 8 ms: http://stackoverflow.com/a/12073686/353094 – leetNightshade

+3

@leetNightshade Dicho esto en Python 3.4.1 x86 este método es el más rápido de acuerdo con mis puntos de referencia. – leetNightshade

21

Esta es la reactivación de una vieja pregunta, pero en Python 3, sólo puede utilizar bytes directamente:

>>> bytes([17, 24, 121, 1, 12, 222, 34, 76]) 
b'\x11\x18y\x01\x0c\xde"L' 
+0

¡Excelente, limpio y simple! –

+0

Esta es probablemente la respuesta "más correcta" para python3 –

+0

¿Cómo hacer exactamente lo contrario? (bytes -> matriz) – Tino

0

Shorter versión del anterior en el mapa() función (que funciona para Python 2.7):

"".join(map(chr, myList))

Cuestiones relacionadas