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.