Von einer in Hex codierten ASCII-Zeichenfolge in eine einfache ASCII-Zeichenfolge konvertieren?

146

Wie kann ich in Python von hexadezimalem zu einfachem ASCII konvertieren?

Beachten Sie, dass ich beispielsweise "0x7061756c" in "paul" konvertieren möchte.

Paul Reiners
quelle
Ich habe ein paar Sachen ausprobiert, die ich hier gefunden habe: docs.python.org/library/binascii.html
Paul Reiners
1
Mit Hilfe des Links, den Sie uns gerade gegeben haben, habe ich die gesuchte Funktion gefunden. Was genau hast du versucht und warum hat es nicht funktioniert?
Vincent Savard
1
Ich habe Folgendes versucht: >>> 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 ("0x706135> .b2a_hex (0x7061756c) Traceback (letzter Aufruf zuletzt): Datei "<stdin>", Zeile 1, in <module> TypeError: muss Zeichenfolge oder Puffer sein, nicht int >>>
Paul Reiners
Keiner von ihnen arbeitete, weil keiner von ihnen "Paul" zurückgab.
Paul Reiners
2
Meinen Sie nicht "7-Bit" ASCII? (Was irgendwie albern ist, weil ASCII nur 7-Bit ist.) Eine GUID ist 128 Bit ...

Antworten:

231

Eine etwas einfachere Lösung:

>>> "7061756c".decode("hex")
'paul'
cjm
quelle
142
In .decode('hex')Python 3 gibt es keine .decode('hex')Verwendung binascii.unhexlify()in Python 2 .
JFS
2
Vielen Dank für den Hinweis, dass ich mit Python 3 nicht so vertraut bin. Soweit ich weiß, funktioniert diese Lösung auch nicht in 1.
cjm
26
codecs.decode("7061756c", "hex")funktioniert für Python 2 und Python 3. bytes()In Python 3 wird jedoch eine Zeichenfolge zurückgegeben. Für eine ASCII-Zeichenfolge ist dies jedoch sinnvoll.
Mark Evans
100

Sie müssen keine Bibliothek importieren:

>>> bytearray.fromhex("7061756c").decode()
'paul'
user4369081
quelle
2
Beste Lösung für mich (funktioniert mit Python 3), da es sogar Leerzeichen akzeptiert:bytearray.fromhex("70 61 75 6C").decode()
Jona
bytearray.fromhex ("70e4756c"). decode (encoding = "Latin1") 'päul' Für diejenigen von uns, die in Binärform spielen, ersticken die erweiterten Zeichen an der Standard-utf-8-Decodierung. Abgesehen davon ist dies die portabelste Antwort Aha! Vielen Dank!
Grambo
Natürlich müssen Sie die tatsächliche Kodierung der Daten kennen, wenn sie als Text interpretiert werden sollen. Durch 'latin-1'die Verwendung werden alle Fehler beseitigt, es kann jedoch zu vollständigem Kauderwelsch kommen, wenn der Text nicht tatsächlich Latin-1 ist.
Tripleee
43
>>> txt = '7061756c'
>>> ''.join([chr(int(''.join(c), 16)) for c in zip(txt[0::2],txt[1::2])])
'paul'                                                                          

Ich habe nur Spaß, aber die wichtigen Teile sind:

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

werde jetzt binascii anschauen ...

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

cool (und ich habe keine Ahnung, warum andere Leute dich durch Reifen springen lassen wollen, bevor sie helfen).

Andrew Cooke
quelle
16

In Python 2:

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

In Python 3:

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

Hier ist meine Lösung, wenn ich mit hexadezimalen Ganzzahlen und nicht mit hexadezimalen Zeichenfolgen arbeite:

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)
carloserivera
quelle
+1 für ein nützliches Beispiel, aber Sie konvertieren nicht "hex" als Eingabe, sondern eine beliebige Ganzzahl in eine hexadezimale Zeichenfolge. Ihr Code funktioniert genauso gut mit print convert_hex_to_ascii(123456).
Mark Lakata
5

Alternativ können Sie dies auch tun ...

Python 2 Interpreter

print "\x70 \x61 \x75 \x6c"

Beispiel

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:~# 

oder

Python 2 Einzeiler

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

Beispiel

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

Python 3 Interpreter

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 Einzeiler

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

Beispiel

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

user@linux:~$ python -c 'print("\x70\x61\x75\x6c")'
paul
Sabrina
quelle
2
Dies funktioniert auch ohne Leerzeichen und in Python3 mit print ().
rjferguson
Ja, ich habe es absichtlich gemacht, um es besser sehen zu können. Lassen Sie mich die Antwort auch mit Python 3 aktualisieren.
Sabrina
3

In Python 3.3.2 getestet Es gibt viele Möglichkeiten, dies zu erreichen. Hier ist eine der kürzesten, bei der nur von Python bereitgestellte Inhalte verwendet werden:

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

Wenn Sie nichts importieren möchten, können Sie natürlich jederzeit Ihren eigenen Code schreiben. Etwas sehr Grundlegendes wie dieses:

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)
Victor Barrantes
quelle
1
b''.fromhex('7061756c')

Verwenden Sie es ohne Trennzeichen

Heiser
quelle