¿Cómo convertir una cadena hexadecimal a bytes en Python?

2 minutos de lectura

Avatar de usuario de Richard
Ricardo

Tengo una cadena hexadecimal larga que representa una serie de valores de diferentes tipos. Necesito convertir esta cadena hexadecimal en bytes o bytearray para que pueda extraer cada valor de los datos sin procesar. ¿Cómo puedo hacer esto?

Por ejemplo, la cadena "ab" debe convertir a los bytes b"\xab" o matriz de bytes equivalente. Ejemplo más largo:

>>> # what to use in place of `convert` here?
>>> convert("8e71c61de6a2321336184f813379ec6bf4a3fb79e63cd12b")
b'\x8eq\xc6\x1d\xe6\xa22\x136\x18O\x813y\xeck\xf4\xa3\xfby\xe6<\xd1+'

  • ¿Cómo se ve esa cadena hexagonal?

    – khachik

    13 de abril de 2011 a las 12:46

avatar de usuario de tzot
tzot

Supongamos que su cadena hexadecimal es algo así como

>>> hex_string = "deadbeef"

Conviértalo en un bytearray (Python 3 y 2.7):

>>> bytearray.fromhex(hex_string)
bytearray(b'\xde\xad\xbe\xef')

Conviértalo en un objeto de bytes (Python 3):

>>> bytes.fromhex(hex_string)
b'\xde\xad\xbe\xef'

Tenga en cuenta que bytes es una versión inmutable de bytearray.

Conviértalo en una cadena (Python ≤ 2.7):

>>> hex_data = hex_string.decode("hex")
>>> hex_data
"\xde\xad\xbe\xef"

  • Nota eso bytes.fromhex arroja un error cuando la cadena de entrada tiene un número impar de caracteres: bytes.fromhex("aab")ValueError: non-hexadecimal number found in fromhex() arg at position 3.

    – Константин Ван

    24/07/2018 a las 17:35


  • La nueva versión de hex_string.decode("hex") es codecs.decode(hex_string, 'hex').

    – wjandrea

    30 de junio de 2022 a las 19:42

Hay una función incorporada en bytearray que hace lo que pretendes.

bytearray.fromhex("de ad be ef 00")

Devuelve un bytearray y lee cadenas hexadecimales con o sin separador de espacios.

  • La mejor respuesta seguro!

    – Maiku Mori

    5 de junio de 2014 a las 11:33

  • Esto funciona en Python 3, mientras que hex_string.decode("hex") no es.

    – Eric O Lebigot

    22 de febrero de 2015 a las 10:22

siempre que haya entendido correctamente, debe buscar binascii.unhexlify

import binascii
a="45222e"
s=binascii.unhexlify(a)
b=[ord(x) for x in s]

  • Estoy de acuerdo que unhexlify es la forma más eficiente de ir aquí, pero sugeriría que b = bytearray(s) sería mejor que usar ord. Como Python tiene un tipo incorporado solo para matrices de bytes, me sorprende que nadie lo esté usando

    – Scott Griffiths

    13 de abril de 2011 a las 15:03


Asumiendo que tienes una cadena de bytes así

“\x12\x45\x00\xAB”

y conoce la cantidad de bytes y su tipo, también puede usar este enfoque

import struct

bytes="\x12\x45\x00\xAB"
val = struct.unpack('<BBH', bytes)

#val = (18, 69, 43776)

Como especifiqué little endian (usando el carácter ‘

0x12 = 18

0x45 = 69

0xAB00 = 43776

B es igual a un byte (8 bits) sin signo

H es igual a dos bytes (16 bits) sin firmar

Más caracteres disponibles y tamaños de bytes se pueden encontrar aquí

Las ventajas son..

Puede especificar más de un byte y el endian de los valores

Desventajas..

Realmente necesita saber el tipo y la longitud de los datos con los que está tratando

avatar de usuario de velsim
Velsim

Puedes usar el Módulo de códecs en la biblioteca estándar de Python, es decir

import codecs

codecs.decode(hexstring, 'hex_codec')

avatar de usuario de unwind
relajarse

Debería poder construir una cadena que contenga los datos binarios usando algo como:

data = "fef0babe"
bits = ""
for x in xrange(0, len(data), 2)
  bits += chr(int(data[x:x+2], 16))

Probablemente esta no sea la forma más rápida (muchas cadenas agregan), pero es bastante simple usando solo el núcleo de Python.

avatar de usuario de karlw
carlos

Un buen trazador de líneas es:

byte_list = map(ord, hex_string)

Esto iterará sobre cada carácter en la cadena y lo ejecutará a través de la función ord(). Solo probado en python 2.6, no estoy muy seguro acerca de 3.0+.

-Josh

  • perfecto. Trabajando en python 2.7

    – Ricardo

    13 de abril de 2011 a las 13:06

  • ¡Haga clic en el contorno de la marca de verificación junto a esta respuesta si es la correcta! 🙂

    – jatanismo

    13 de abril de 2011 a las 13:54

  • Esto no convierte hexadecimal, convierte cada carácter de una cadena en un número entero. Para hexadecimal, cada par de caracteres representaría un byte. También podrías decir byte_list = bytearray(hex_string)

    – Scott Griffiths

    13 de abril de 2011 a las 15:11

¿Ha sido útil esta solución?