¿Cómo puedo convertir una cadena de bytes en un int en python?
Diga así: 'y\xcc\xa6\xbb'
Se me ocurrió una forma inteligente / estúpida de hacerlo:
sum(ord(c) << (i * 8) for i, c in enumerate('y\xcc\xa6\xbb'[::-1]))
Sé que tiene que haber algo incorporado o en la biblioteca estándar que haga esto de manera más simple ...
Esto es diferente de convertir una cadena de dígitos hexadecimales para los que puede usar int (xxx, 16), pero en su lugar quiero convertir una cadena de valores de bytes reales.
ACTUALIZAR:
Me gusta un poco la respuesta de James porque no requiere importar otro módulo, pero el método de Greg es más rápido:
>>> from timeit import Timer
>>> Timer('struct.unpack("<L", "y\xcc\xa6\xbb")[0]', 'import struct').timeit()
0.36242198944091797
>>> Timer("int('y\xcc\xa6\xbb'.encode('hex'), 16)").timeit()
1.1432669162750244
Mi método hacky:
>>> Timer("sum(ord(c) << (i * 8) for i, c in enumerate('y\xcc\xa6\xbb'[::-1]))").timeit()
2.8819329738616943
ACTUALIZACIÓN ADICIONAL:
Alguien preguntó en los comentarios cuál es el problema con la importación de otro módulo. Bueno, importar un módulo no es necesariamente barato, eche un vistazo:
>>> Timer("""import struct\nstruct.unpack(">L", "y\xcc\xa6\xbb")[0]""").timeit()
0.98822188377380371
Incluyendo el costo de importar el módulo niega casi todas las ventajas que tiene este método. Creo que esto solo incluirá el gasto de importarlo una vez para toda la prueba de referencia; mira lo que sucede cuando lo obligo a recargar cada vez:
>>> Timer("""reload(struct)\nstruct.unpack(">L", "y\xcc\xa6\xbb")[0]""", 'import struct').timeit()
68.474128007888794
No hace falta decir que si realiza muchas ejecuciones de este método por importación, esto proporcionalmente será un problema menor. También es probable que sea un costo de E / S en lugar de una CPU, por lo que puede depender de la capacidad y las características de carga de la máquina en particular.
int.from_bytes
) se superó struct.unpack
en mi computadora. Junto a ser más legible imo.