¿Convertir de cadena ASCII codificada en hexadecimal a ASCII simple?


147

¿Cómo puedo convertir de hexadecimal a ASCII simple en Python?

Tenga en cuenta que, por ejemplo, quiero convertir "0x7061756c" a "Paul".


He probado un montón de cosas que encontré aquí: docs.python.org/library/binascii.html
Paul Reiners

1
Con la ayuda del enlace que nos acaba de dar, encontré la función que estaba buscando. ¿Qué probaste exactamente y por qué no funcionó?
Vincent Savard

1
Intenté lo siguiente: >>> binascii.b2a_hqx ("0x7061756c") '- (Jh- $ Ba0c8fB`' >>> binascii.b2a_uu ("0x7061756c") "*, '@ W, # 8Q-S4V8P \ n" >>> binascii. .b2a_hex (0x7061756c) Traceback (última llamada más reciente): Archivo "<stdin>", línea 1, en <module> TypeError: debe ser string o buffer, no int >>>
Paul Reiners

Ninguno de ellos trabajó, porque ninguno de ellos regresó 'Paul'.
Paul Reiners

2
¿No quieres decir ASCII de "7 bits"? (Lo cual es un poco tonto porque ASCII tiene solo 7 bits). Un GUID es de 128 bits ...

Respuestas:


231

Una solución un poco más simple:

>>> "7061756c".decode("hex")
'paul'

143
no hay .decode('hex')en Python 3. .decode('hex')usos binascii.unhexlify()en Python 2 .
jfs

2
Gracias por señalarlo, no estoy tan familiarizado con Python 3. Esta solución tampoco funcionará en 1 hasta donde yo sé.
cjm

27
codecs.decode("7061756c", "hex")funciona para Python 2 y Python 3. Pero devuelve una bytes()cadena en Python 3. Pero eso es razonable para una cadena ASCII.
Mark Evans

101

No es necesario importar ninguna biblioteca:

>>> bytearray.fromhex("7061756c").decode()
'paul'

2
La mejor solución para mí (funciona con Python 3) ya que incluso acepta espacios:bytearray.fromhex("70 61 75 6C").decode()
Jona

bytearray.fromhex ("70e4756c"). decode (encoding = "Latin1") 'päul' Para aquellos de nosotros que jugamos en binario, los caracteres extendidos se ahogan en la decodificación utf-8 predeterminada, aparte de eso, esta es la respuesta más portátil ¡Veo! ¡Gracias!
grambo

Por supuesto, debe conocer la codificación real de los datos si debe interpretarse como texto. El uso 'latin-1'eliminará cualquier error, pero puede producir un galimatías completo si el texto no es realmente latino-1.
tripleee

43
>>> txt = '7061756c'
>>> ''.join([chr(int(''.join(c), 16)) for c in zip(txt[0::2],txt[1::2])])
'paul'                                                                          

Me estoy divirtiendo, pero las partes importantes son:

>>> int('0a',16)         # parse hex
10
>>> ''.join(['a', 'b'])  # join characters
'ab'
>>> 'abcd'[0::2]         # alternates
'ac'
>>> zip('abc', '123')    # pair up
[('a', '1'), ('b', '2'), ('c', '3')]        
>>> chr(32)              # ascii to character
' '

mirará a binascii ahora ...

>>> print binascii.unhexlify('7061756c')
paul

genial (y no tengo idea de por qué otras personas quieren hacerte saltar a través de los aros antes de que ayuden).


16

En Python 2:

>>> "7061756c".decode("hex")
'paul'

En Python 3:

>>> bytes.fromhex('7061756c').decode('utf-8')
'paul'

5

Aquí está mi solución cuando trabajo con enteros hexadecimales y no con cadenas hexadecimales:

def convert_hex_to_ascii(h):
    chars_in_reverse = []
    while h != 0x0:
        chars_in_reverse.append(chr(h & 0xFF))
        h = h >> 8

    chars_in_reverse.reverse()
    return ''.join(chars_in_reverse)

print convert_hex_to_ascii(0x7061756c)

+1 para un ejemplo útil, pero no está convirtiendo "hexadecimal" como entrada, sino que está convirtiendo cualquier número entero en una cadena hexadecimal. Tu código funcionará igual de bien con print convert_hex_to_ascii(123456).
Mark Lakata

5

Alternativamente, también puedes hacer esto ...

Python 2 Intérprete

print "\x70 \x61 \x75 \x6c"

Ejemplo

user@linux:~# python
Python 2.7.14+ (default, Mar 13 2018, 15:23:44) 
[GCC 7.3.0] on linux2
Type "help", "copyright", "credits" or "license" for more information.

>>> print "\x70 \x61 \x75 \x6c"
p a u l
>>> exit()
user@linux:~# 

o

Python 2 One-Liner

python -c 'print "\x70 \x61 \x75 \x6c"'

Ejemplo

user@linux:~# python -c 'print "\x70 \x61 \x75 \x6c"'
p a u l
user@linux:~# 

Python 3 Intérprete

user@linux:~$ python3
Python 3.6.9 (default, Apr 18 2020, 01:56:04) 
[GCC 8.4.0] on linux
Type "help", "copyright", "credits" or "license" for more information.

>>> print("\x70 \x61 \x75 \x6c")
p a u l

>>> print("\x70\x61\x75\x6c")
paul

Python 3 One-Liner

python -c 'print("\x70 \x61 \x75 \x6c")'

Ejemplo

user@linux:~$ python -c 'print("\x70 \x61 \x75 \x6c")'
p a u l

user@linux:~$ python -c 'print("\x70\x61\x75\x6c")'
paul

2
Esto funciona bien sin los espacios también, y funciona bien en python3 con print ().
rjferguson

Sí, lo puse a propósito para que sea más fácil de ver. Permítanme actualizar la respuesta con Python 3 también.
Sabrina

3

Probado en Python 3.3.2 Hay muchas maneras de lograr esto, esta es una de las más cortas, usando solo cosas proporcionadas por Python:

import base64
hex_data ='57696C6C20796F7520636F6E76657274207468697320484558205468696E6720696E746F20415343494920666F72206D653F2E202E202E202E506C656565656173652E2E2E212121'
ascii_string = str(base64.b16decode(hex_data))[2:-1]
print (ascii_string)

Por supuesto, si no desea importar nada, siempre puede escribir su propio código. Algo muy básico como este:

ascii_string = ''
x = 0
y = 2
l = len(hex_data)
while y <= l:
    ascii_string += chr(int(hex_data[x:y], 16))
    x += 2
    y += 2
print (ascii_string)

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.