Convertir una cadena hexadecimal en entero con python

Tenga en cuenta que el problema no es de hexadecimal a decimal sino de una cadena de valores hexadecimales a entero.

Digamos que tengo una picadura de un hexdump (por ejemplo, ‘6c 02 00 00’), así que primero tengo que convertirlo en hexágono real, y luego obtener el entero que representa … (este en particular sería 620 como un int16 y int32)

Probé muchas cosas pero me confundí más. ¿Hay una manera rápida de hacer tal conversión en python (preferiblemente 3.x)?

No solo es una cadena, sino que está en un orden poco endian, lo que significa que solo se eliminarán los espacios y el uso int(xx, 16) llamada int(xx, 16) funcionará. Tampoco tiene los valores de byte reales como 4 números 0-255 arbitrarios (en cuyo caso, struct.unpack funcionaría).

Creo que un buen enfoque es intercambiar los componentes nuevamente en orden “legible por humanos” y usar la llamada int, por lo tanto:

 number = int("".join("6c 02 00 00".split()[::-1]), 16) 

Lo que sucede allí: la primera parte de la expesión es la split : rompe la cadena en los espacios y proporciona una lista con cuatro cadenas, dos dígitos en cada una. La división especial [:: – 1] es la siguiente: significa más o menos “proporcionarme un subconjunto de elementos de la secuencia anterior, empezando por los bordes y retrocediendo 1 elemento a la vez”, que es un lenguaje común de Python para invertir cualquier secuencia

Esta secuencia invertida se usa en la llamada a "".join(...) , que básicamente utiliza la cadena vacía como un concatenador para cada elemento de la secuencia; el resultado de esta llamada es “0000026c”. Con este valor, simplemente llamamos a la clase int de Python, que acepta un parámetro opcional secundario que denota la base que debe usarse para interpretar el número denotado en el primer argumento.

 >>> int("".join("6c 02 00 00".split()[::-1]), 16) 620 

Otra opción, es sumr acumulativamente la conversión de cada 2 dígitos, apropiadamente desplazados a su peso de acuerdo a su posición; esto también se puede hacer en una sola expresión usando reduce , aunque un Python for loop de 4 líneas sería más legible:

 >>> from functools import reduce #not needed in Python2.x >>> reduce(lambda x, y: x + (int(y[1], 16)<<(8 * y[0]) ), enumerate("6c 02 00 00".split()), 0) 620 

actualizar El OP acaba de decir que en realidad no tiene los "espacios" en la cadena; en ese caso, uno puede usar solo los mismos métodos, pero tomando cada dos dígitos en lugar de la llamada split() :

 reduce(lambda x, y: x + (int(y[1], 16)<<(8 * y[0]//2) ), ((i, a[i:i+2]) for i in range(0, len(a), 2)) , 0) 

(donde a es la variable con sus dígitos, por supuesto) - O, conviértalo a un número real de 4 bytes en la memoria, use el códec hexadecimal y descomprima el número con struct. Esto puede ser más correcto para su código:

 import codecs import struct struct.unpack(" 

Entonces, el enfoque aquí es pasar cada 2 dígitos a un byte real en la memoria en un objeto de bytes devuelto por la llamada codecs.decode , y la estructura para leer los 4 bytes en el búfer como un solo entero de 32 bits.

Puede usar unhexlify() para convertir la cadena hexadecimal a su forma binaria, y luego usar struct.unpack() para decodificar el valor little little endian en un int:

 >>> from struct import unpack >>> from binascii import unhexlify >>> n = unpack('>> n 

La cadena de formato ' significa pequeño entero con signo endian. Puede sustituir con ' o ' para int sin signo o largo (ambos 4 bytes).

Si los datos no contienen espacios, esto se simplifica a

 >>> n = unpack('