Hex olarak kodlanmış ASCII dizesinden düz ASCII'ye dönüştürülsün mü?


154

Python'da hex'den düz ASCII'ye nasıl dönüştürebilirim?

Örneğin, "0x7061756c" yi "paul" 'a dönüştürmek istediğime dikkat edin.


Burada bulduğum birçok şeyi denedim: docs.python.org/library/binascii.html
Paul Reiners

1
Bize az önce verdiğiniz link yardımıyla aradığınız işlevi buldum. Ne tam olarak sen denedin mi ve neden işe yaramadı?
Vincent Savard

1
Şunu denedim: >>> 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") ' .b2a_hex (0x7061756c) Geri izleme (en son çağrı): Dosya "<stdin>", satır 1, <module> TypeError: dizge veya arabellek olmalıdır, int değil >>>
Paul Reiners

Hiçbiri işe yaramadı çünkü hiçbiri 'paul'u geri vermedi.
Paul Reiners

2
"7-bit" ASCII'den mi bahsediyorsun? (Bu biraz aptalca çünkü ASCII sadece 7 bittir.) Bir GUID 128

Yanıtlar:


234

Biraz daha basit bir çözüm:

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

150
jfs

2
Bunu belirttiğiniz için teşekkürler, Python 3'e aşina değilim. Bu çözüm de bildiğim kadarıyla 1'de çalışmayacak.
cjm

27
codecs.decode("7061756c", "hex")Python 2 ve Python 3 için çalışır. Ancak Python 3'te bir bytes()dize döndürür . Ancak bu bir ASCII dizesi için mantıklıdır.
Mark Evans

113

Herhangi bir kitaplığı içe aktarmaya gerek yok:

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

2
Boşlukları bile kabul ettiği için benim için en iyi çözüm (python 3 ile çalışır):bytearray.fromhex("70 61 75 6C").decode()
Jona

bytearray.fromhex ("70e4756c"). decode (encoding = "Latin1") 'päul' İkili olarak oynayan bizler için, genişletilmiş karakterler varsayılan utf-8 kod çözme işleminde boğulur, bunun dışında, bu en taşınabilir yanıttır Anlıyorum! Teşekkürler!
grambo

Tabii ki , metin olarak yorumlanacaksa, verilerin gerçek kodlamasını bilmeniz gerekir. Kullanmak 'latin-1'herhangi bir hatayı ortadan kaldırır, ancak metin aslında Latin-1 değilse tam anlamıyla anlamsız şeyler üretebilir.
üçlü

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

sadece eğleniyorum ama önemli kısımlar:

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

şimdi binascii'ye bakacak ...

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

havalı (ve diğer insanların neden yardım etmeden önce sizi çemberden atlatmak istedikleri hakkında hiçbir fikrim yok).


20

Python 2'de:

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

Python 3'te:

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

5

İşte onaltılık dizelerle değil onaltılık tamsayılarla çalışırken çözümüm:

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)

Kullanışlı bir örnek için +1, ancak girdi olarak "onaltılık" 'ı dönüştürmüyorsunuz, ancak herhangi bir tamsayıyı onaltılık dizeye dönüştürüyorsunuz. Kodunuz aynı şekilde çalışacaktır print convert_hex_to_ascii(123456).
Mark Lakata

4

Alternatif olarak, bunu da yapabilirsiniz ...

Python 2 Yorumlayıcı

print "\x70 \x61 \x75 \x6c"

Misal

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

veya

Python 2 Tek Sıralı

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

Misal

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

Python 3 Yorumlayıcı

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 Tek Sıralı

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

Misal

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

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

2
Bu boşluklar olmadan da iyi çalışır ve python3'te print () ile sorunsuz çalışır.
rjferguson

1
Evet, görmeyi kolaylaştırmak için bilerek koydum. Cevabı Python 3 ile de güncellememe izin verin.
Sabrina

3

Python 3.3.2'de test edilmiştir Bunu başarmanın birçok yolu vardır, işte en kısalarından biri, yalnızca python tarafından sağlanan şeyleri kullanarak:

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

Elbette, hiçbir şey içe aktarmak istemiyorsanız, her zaman kendi kodunuzu yazabilirsiniz. Bunun gibi çok basit bir şey:

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)

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

sınırlayıcı olmadan kullan

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.