Convertir une chaîne ASCII codée en hexadécimal en ASCII brut?

147

Comment puis-je convertir de l'hexagone en ASCII brut en Python?

Notez que, par exemple, je veux convertir "0x7061756c" en "paul".

Paul Reiners
la source
J'ai essayé un tas de trucs que j'ai trouvés ici: docs.python.org/library/binascii.html
Paul Reiners
1
Avec l'aide du lien que vous venez de nous donner, j'ai trouvé la fonction que vous recherchiez. Qu'as -tu essayé exactement et pourquoi ça n'a pas marché?
Vincent Savard
1
J'ai essayé ce qui suit: >>> 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 ("0x7061756c") '3078936 .b2a_hex (0x7061756c) Traceback (dernier appel le plus récent): Fichier "<stdin>", ligne 1, dans <module> TypeError: doit être une chaîne ou un tampon, pas un int >>>
Paul Reiners
Aucun d'entre eux n'a fonctionné, car aucun d'entre eux n'a renvoyé «paul».
Paul Reiners
2
Vous ne voulez pas dire ASCII "7 bits"? (Ce qui est un peu idiot car ASCII n'est que de 7 bits.) Un GUID est de 128 bits ...

Réponses:

231

Une solution un peu plus simple:

>>> "7061756c".decode("hex")
'paul'
cjm
la source
143
il n'y a pas .decode('hex')sur Python 3. .decode('hex')utilise binascii.unhexlify()sur Python 2 .
jfs
2
Merci d'avoir signalé cela, je ne suis pas aussi familier avec Python 3. Cette solution ne fonctionnera pas non plus en 1 pour autant que je sache.
cjm
27
codecs.decode("7061756c", "hex")fonctionne pour Python 2 et Python 3. Mais il renvoie une bytes()chaîne en Python 3. Mais c'est raisonnable pour une chaîne ASCII.
Mark Evans
101

Pas besoin d'importer de bibliothèque:

>>> bytearray.fromhex("7061756c").decode()
'paul'
user4369081
la source
2
Meilleure solution pour moi (fonctionne avec python 3) car il accepte même les espaces:bytearray.fromhex("70 61 75 6C").decode()
Jona
bytearray.fromhex ("70e4756c"). decode (encoding = "Latin1") 'päul' Pour ceux d'entre nous qui jouent en binaire, les caractères étendus s'étouffent avec le décodage utf-8 par défaut, à part cela, c'est la réponse la plus portable Je vois! Merci!
grambo
Bien sûr, vous devez connaître le codage réel des données si elles doivent être interprétées comme du texte. L'utilisation 'latin-1'éliminera toutes les erreurs, mais pourrait bien produire un charabia complet si le texte n'est pas réellement Latin-1.
tripleee
43
>>> txt = '7061756c'
>>> ''.join([chr(int(''.join(c), 16)) for c in zip(txt[0::2],txt[1::2])])
'paul'                                                                          

je m'amuse juste, mais les parties importantes sont:

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

va regarder binascii maintenant ...

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

cool (et je ne sais pas pourquoi d'autres personnes veulent vous faire sauter à travers des cerceaux avant de vous aider).

Andrew Cooke
la source
16

Dans Python 2:

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

Dans Python 3:

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

Voici ma solution lorsque vous travaillez avec des entiers hexadécimaux et non des chaînes hexadécimales:

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
la source
+1 pour un exemple utile, mais vous ne convertissez pas «hexadécimal» comme entrée, mais vous convertissez n'importe quel entier en chaîne hexadécimale. Votre code fonctionnera également avec print convert_hex_to_ascii(123456).
Mark Lakata
5

Alternativement, vous pouvez également le faire ...

Interpréteur Python 2

print "\x70 \x61 \x75 \x6c"

Exemple

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

ou

Python 2 One-Liner

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

Exemple

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

Interpréteur 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")'

Exemple

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

user@linux:~$ python -c 'print("\x70\x61\x75\x6c")'
paul
Sabrina
la source
2
Cela fonctionne aussi bien sans les espaces, et fonctionne bien en python3 avec print ().
rjferguson
Oui, je l'ai mis exprès pour le rendre plus facile à voir. Permettez-moi également de mettre à jour la réponse avec Python 3.
Sabrina
3

Testé en Python 3.3.2 Il existe de nombreuses façons d'accomplir cela, voici l'une des plus courtes, en utilisant uniquement des éléments fournis par python:

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

Bien sûr, si vous ne voulez rien importer, vous pouvez toujours écrire votre propre code. Quelque chose de très basique comme ça:

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
la source
1
b''.fromhex('7061756c')

utilisez-le sans délimiteur

Rauque
la source