Convertire da stringa ASCII codificata in esadecimale in semplice ASCII?


147

Come posso convertire da hex a plain ASCII in Python?

Nota che, ad esempio, voglio convertire "0x7061756c" in "paul".


Ho provato un sacco di cose che ho trovato qui: docs.python.org/library/binascii.html
Paul Reiners

1
Con l'aiuto del link che ci hai appena fornito, ho trovato la funzione che stavi cercando. Cosa hai provato esattamente e perché non ha funzionato?
Vincent Savard,

1
Ho provato quanto segue: >>> binascii.b2a_hqx ("0x7061756c") '- (Jh- $ Ba0c8fB`' >>> binascii.b2a_uu ("0x7061756c") "*, '@ W, # 8Q-S4V8P \ n" >>> binascii.b2a_base64 ("0x7061756c") 'MHg3MDYxNzU2Yw == \ n' >>> binascii.b2a_qp ("0x7061756c") '0x7061756c' >>> binascii.b2a_hex ("0x3636756c .b2a_hex (0x7061756c) Traceback (ultima chiamata più recente): File "<stdin>", linea 1, in <module> TipoErrore: deve essere stringa o buffer, non int >>>
Paul Reiners

Nessuno di loro ha funzionato, perché nessuno di loro ha restituito "Paul".
Paul Reiners,

2
Non intendi ASCII "7 bit"? (Che è un po 'sciocco perché ASCII è solo 7 bit.) Un GUID è

Risposte:


231

Una soluzione leggermente più semplice:

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

143
non c'è .decode('hex')su Python 3. .decode('hex')utilizza binascii.unhexlify()su Python 2 .
jfs

2
Grazie per averlo sottolineato, non ho familiarità con Python 3. Anche questa soluzione non funzionerà in 1 per quanto ne so.
cjm

27
codecs.decode("7061756c", "hex")funziona per Python 2 e Python 3. Ma restituisce una bytes()stringa in Python 3. Ma è ragionevole per una stringa ASCII.
Mark Evans,

101

Non è necessario importare alcuna libreria:

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

2
La migliore soluzione per me (funziona con Python 3) in quanto accetta anche spazi:bytearray.fromhex("70 61 75 6C").decode()
Jona

bytearray.fromhex ("70e4756c"). decode (encoding = "Latin1") 'päul' Per quelli di noi che giocano in binario, i caratteri estesi si strozzano con la decodifica utf-8 predefinita, a parte questo, questa è la risposta più portatile Vedo! Grazie!
grambo,

Ovviamente devi conoscere la codifica effettiva dei dati se deve essere interpretata come testo. L'utilizzo 'latin-1'eliminerà tutti gli errori, ma potrebbe produrre una completa incomprensione se il testo non è effettivamente Latin-1.
Tripleee

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

mi sto solo divertendo, ma le parti importanti sono:

>>> 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
' '

guarderò binascii ora ...

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

fico (e non ho idea del perché le altre persone vogliono farti saltare attraverso i cerchi prima che possano aiutarti).


16

In Python 2:

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

In Python 3:

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

5

Ecco la mia soluzione quando si lavora con numeri esadecimali e non stringhe esadecimali:

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 per un esempio utile, ma non stai convertendo "hex" come input ma stai convertendo qualsiasi numero intero in una stringa esadecimale. Il tuo codice funzionerà allo stesso modo anche con print convert_hex_to_ascii(123456).
Mark Lakata,

5

In alternativa, puoi anche farlo ...

Interprete Python 2

print "\x70 \x61 \x75 \x6c"

Esempio

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"'

Esempio

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

Interprete Python 3

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")'

Esempio

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

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

2
Funziona bene anche senza gli spazi, e funziona bene in python3 con print ().
rjferguson,

Sì, l'ho messo apposta per renderlo più facile da vedere. Vorrei aggiornare anche la risposta con Python 3.
Sabrina,

3

Testato in Python 3.3.2 Esistono molti modi per farlo, ecco uno dei più brevi, usando solo materiale fornito da Python:

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

Naturalmente, se non vuoi importare nulla, puoi sempre scrivere il tuo codice. Qualcosa di molto semplice come questo:

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)

1
b''.fromhex('7061756c')

usalo senza delimitatore

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.