Перетворити з ASCII рядка, закодованого в Hex, в звичайний ASCII?


147

Як я можу перетворити з шестигранної на звичайну ASCII в Python?

Зауважте, що, наприклад, я хочу перетворити "0x7061756c" в "paul".


Я спробував купу матеріалів, які я знайшов тут: docs.python.org/library/binascii.html
Пол Рейндерс

1
За допомогою посилання, яке ви тільки що нам дали, я знайшов функцію, яку ви шукали. Що саме ви спробували і чому це не вийшло?
Вінсент Савард

1
Я спробував наступне: >>> binascii.b2a_hqx ("0x7061756c") '- (Jh- $ Ba0c8fB`' >>> binascii.b2a_uu ("0x7061756c") "*, '@ W, # 8Q-S4V8P \ n" > .b2a_hex (0x7061756c) Traceback (останній дзвінок останній): Файл "<stdin>", рядок 1, в <module> TypeError: повинен бути рядок або буфер, а не int >>>
Пол Рейнерс

Жоден з них не працював, тому що ніхто з них не повернувся "паулом".
Пол Райнерс

2
Ви не маєте на увазі "7-бітний" ASCII? (Що начебто нерозумно, тому що ASCII - це лише 7-біт.) GUID - 128 біт ...

Відповіді:


231

Трохи простіше рішення:

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


2
Дякую за те, що я вказав, що я не так знайомий з Python 3. Це рішення також не працюватиме в 1, наскільки я знаю.
cjm

27
codecs.decode("7061756c", "hex")працює для Python 2 та Python 3. Але він повертає bytes()рядок у Python 3. Але це обґрунтовано для рядка ASCII.
Марк Еванс

101

Не потрібно імпортувати жодну бібліотеку:

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

2
Найкраще рішення для мене (працює з python 3), оскільки він навіть приймає пробіли:bytearray.fromhex("70 61 75 6C").decode()
Jona

bytearray.fromhex ("70e4756c"). decode (encoding = "Latin1") 'päul' Для тих, хто грає у двійковій формі, розширені символи задихаються на декодуванні utf-8 за замовчуванням, крім цього, це найбільш портативна відповідь Я бачу! Дякую!
грамбо

Звичайно, ви повинні знати фактичне кодування даних, якщо їх слід інтерпретувати як текст. Використання 'latin-1'дозволить позбутися від будь-яких помилок, але цілком може призвести до потворності, якщо текст насправді не є латинським-1.
tripleee

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

Мені просто весело, але важливими частинами є:

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

поглянемо на бінасці зараз ...

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

круто (і я поняття не маю, чому інші люди хочуть змусити вас стрибати через обручі, перш ніж вони допоможуть).


16

У Python 2:

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

У Python 3:

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

5

Ось моє рішення при роботі з шістнадцятковими цілими числами, а не шістнадцятковими рядками:

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 для корисного прикладу, але ви не конвертуєте "шістнадцятковий" як вхідний, але ви перетворюєте будь-яке ціле число в шістнадцяткову рядок. Ваш код буде однаково добре працювати з print convert_hex_to_ascii(123456).
Марк Лаката

5

Крім того, ви також можете це зробити ...

Перекладач Python 2

print "\x70 \x61 \x75 \x6c"

Приклад

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

або

Пітон 2 однолінійний

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

Приклад

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

Перекладач 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

Пітон 3 однолінійний

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

Приклад

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

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

2
Це чудово працює і без пробілів, і чудово працює у python3 з print ().
rjferguson

Так, я поставив це за призначенням, щоб було легше бачити. Дозвольте мені також оновити відповідь на Python 3.
Сабріна

3

Перевірено в Python 3.3.2 Існує багато способів цього досягти, ось один із найкоротших, використовуючи лише матеріали, що надаються python:

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

Звичайно, якщо ви нічого не бажаєте імпортувати, ви завжди можете написати власний код. Щось дуже базове, як це:

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)

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.