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


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'

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'

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).


16

Dans Python 2:

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

Dans Python 3:

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

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)

+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

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)

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

utilisez-le sans délimiteur

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.