แปลงจากสตริง ASCII ที่เข้ารหัสใน Hex เป็น ASCII ธรรมดาหรือไม่


147

ฉันจะแปลงจาก hex เป็น ASCII ธรรมดาใน Python ได้อย่างไร

โปรดทราบว่าตัวอย่างเช่นฉันต้องการแปลง "0x7061756c" เป็น "paul"


ฉันลองสิ่งต่างๆมากมายที่ฉันพบที่นี่: docs.python.org/library/binascii.html
Paul Reiners

1
ด้วยความช่วยเหลือของลิงค์ที่คุณเพิ่งให้เราฉันพบฟังก์ชั่นที่คุณต้องการ สิ่งที่ว่าคุณไม่ลองและทำไมไม่ทำงาน?
Vincent Savard

1
ฉันลองสิ่งต่อไปนี้: >>> binascii.b2a_hqx ("0x7061756c") '- (Jh- $ Ba0c8fB`' >>> binascii.b2a_uu ("0x7061756c") "*, '@ W, # 8Q-S4V8P \ n" >>> binascii.b2a_base64 ("0x7061756c") 'MHg3MDYxNzU2Yw == \ n' >>> binascii.b2a_qq (>>> 0x7061756c ') '0x7061756c' >>> Binascii.b2a_base64 ("0x7061756c") .b2a_hex (0x7061756c) Traceback (การโทรล่าสุดครั้งล่าสุด): ไฟล์ "<stdin>" บรรทัดที่ 1 ใน <module> TypeError TypeError: ต้องเป็นสตริงหรือบัฟเฟอร์ไม่ใช่ int >>>
Paul Reiners

ไม่มีใครทำงานเพราะไม่มีคนใดกลับมา 'พอล'
Paul Reiners

2
คุณไม่หมายถึง ASCII "7 บิต" ใช่หรือไม่ (ซึ่งเป็นประเภทที่โง่เพราะ ASCII เพียง 7 บิต) GUID คือ 128 บิต ...

คำตอบ:


231

ทางออกที่ง่ายกว่าเล็กน้อย:

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

143
ไม่มี.decode('hex')ในหลาม 3. .decode('hex')ใช้binascii.unhexlify()ในหลาม 2
jfs

2
ขอบคุณที่ชี้ให้เห็นว่าฉันไม่คุ้นเคยกับ Python 3 โซลูชันนี้จะไม่ทำงานใน 1 เท่าที่ฉันรู้
cjm

27
codecs.decode("7061756c", "hex")ใช้งานได้กับ Python 2 และ Python 3 แต่จะส่งคืนbytes()สตริงใน Python 3 แต่นั่นก็สมเหตุสมผลสำหรับสตริง ASCII
Mark Evans

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 ที่นอกเหนือไปจากนั้นนี่เป็นคำตอบที่พกพาได้มากที่สุด ฉันเห็น! ขอบคุณ!
grambo

แน่นอนคุณต้องรู้จริงการเข้ารหัสของข้อมูลถ้ามันคือการถูกตีความว่าเป็นข้อความ การใช้'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
' '

จะดูที่ binascii ตอนนี้ ...

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

เจ๋ง (และฉันไม่รู้ว่าทำไมคนอื่นต้องการให้คุณกระโดดผ่านห่วงก่อนที่พวกเขาจะช่วย)



5

นี่คือทางออกของฉันเมื่อทำงานกับจำนวนเต็มฐานสิบหกและไม่ได้สตริง hex:

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 สำหรับตัวอย่างที่มีประโยชน์ แต่คุณไม่ได้แปลง "hex" เป็นอินพุต แต่คุณกำลังแปลงจำนวนเต็มใด ๆ ให้เป็นสตริงฐานสิบหก print convert_hex_to_ascii(123456)รหัสคุณจะทำงานอย่างเท่าเทียมกันเป็นอย่างดีด้วย
Mark Lakata

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

หรือ

Python 2 One-Liner

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

Python 3 One-Liner

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 พร้อมพิมพ์ ()
rjferguson

ใช่ฉันตั้งใจไว้เพื่อให้ง่ายต่อการมองเห็น ให้ฉันอัพเดตคำตอบด้วย Python 3 ด้วย
ซาบรีนา

3

ทดสอบใน Python 3.3.2 มีหลายวิธีในการทำสิ่งนี้ให้สำเร็จนี่คือหนึ่งในวิธีที่สั้นที่สุด

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)

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.