Chuyển đổi từ chuỗi ASCII được mã hóa trong Hex sang ASCII đơn giản?


146

Làm cách nào tôi có thể chuyển đổi từ hex sang ASCII đơn giản trong Python?

Lưu ý rằng, ví dụ, tôi muốn chuyển đổi "0x7061756c" thành "paul".


Tôi đã thử một loạt các công cụ tôi tìm thấy ở đây: docs.python.org/l Library / binascii.html
Paul Reiners

1
Với sự giúp đỡ của liên kết bạn vừa cung cấp cho chúng tôi, tôi đã tìm thấy chức năng bạn đang tìm kiếm. Có gì chính xác bạn đã thử và tại sao không cho nó hoạt động?
Vincent Savard

1
Tôi đã thử như sau: >>> binascii.b2a_hqx ("0x7061756c") '- (Jh- $ Ba0c8fB`' >>> binascii.b2a_uu ("0x7061756c") ", '@ W, # 8Q-S4 >>> binascii.b2a_base64 ("0x7061756c") 'MHg3MDYxNzU2Yw == \ n' >>> binascii.b2a_qp ("0x7061756c") 0x7061756c .b2a_hex (0x7061756c) Traceback (gần đây nhất gọi cuối cùng): file "<stdin>", dòng 1, trong <module> Lỗi Loại: phải chuỗi hoặc đệm, không int >>>
Paul Reiners

Không ai trong số họ làm việc, vì không ai trong số họ trả lại 'paul'.
Paul củng cố

2
Ý bạn là "7-bit" ASCII? (Điều này thật ngớ ngẩn vì ASCII chỉ có 7 bit.) GUID là 128 bit ...

Câu trả lời:


231

Một giải pháp đơn giản hơn một chút:

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

142
không có .decode('hex')trên Python 3. .decode('hex')sử dụng binascii.unhexlify()trên Python 2 .
jfs

2
Cảm ơn bạn đã chỉ ra rằng, tôi không quen thuộc với Python 3. Giải pháp này cũng sẽ không hoạt động trong 1 theo như tôi biết.
cjm

26
codecs.decode("7061756c", "hex")hoạt động cho Python 2 và Python 3. Nhưng nó trả về một bytes()chuỗi trong Python 3. Nhưng điều đó hợp lý cho chuỗi ASCII.
Mark Evans

100

Không cần nhập bất kỳ thư viện:

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

2
Giải pháp tốt nhất cho tôi (hoạt động với python 3) vì nó thậm chí còn chấp nhận khoảng trắng:bytearray.fromhex("70 61 75 6C").decode()
Jona

bytearray.fromhex ("70e4756c"). decode (oding = "Latin1") 'päul' Tôi hiểu rồi! Cảm ơn!
grambo

Tất nhiên bạn phải biết mã hóa thực tế của dữ liệu nếu nó được hiểu là văn bản. Việc sử dụng 'latin-1'sẽ loại bỏ bất kỳ lỗi nào nhưng cũng có thể tạo ra hoàn toàn vô nghĩa nếu văn bản không thực sự là tiếng Latin-1.
tripleee

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

Tôi chỉ vui vẻ, nhưng những phần quan trọng là:

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

sẽ nhìn vào binascii ngay bây giờ ...

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

tuyệt vời (và tôi không biết tại sao người khác muốn làm cho bạn nhảy qua vòng trước khi họ giúp đỡ).


16

Trong Python 2:

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

Trong Python 3:

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

5

Đây là giải pháp của tôi khi làm việc với các số nguyên hex và không phải chuỗi 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 cho một ví dụ hữu ích, nhưng bạn không chuyển đổi "hex" làm đầu vào nhưng bạn đang chuyển đổi bất kỳ số nguyên nào thành chuỗi hex. Mã của bạn sẽ làm việc như nhau với print convert_hex_to_ascii(123456).
Đánh dấu Lakata

5

Ngoài ra, bạn cũng có thể làm điều này ...

Thông dịch viên Python 2

print "\x70 \x61 \x75 \x6c"

Thí dụ

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

hoặc là

Python 2 One-liner

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

Thí dụ

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

Thông dịch viên 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")'

Thí dụ

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

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

2
Điều này hoạt động tốt mà không có khoảng trắng, và hoạt động tốt trong python3 với print ().
rjferguson

Vâng, tôi đặt nó trên mục đích để làm cho nó dễ nhìn hơn. Hãy để tôi cập nhật câu trả lời với Python 3 là tốt.
Sabrina

3

Đã thử nghiệm trong Python 3.3.2 Có nhiều cách để thực hiện việc này, đây là một trong những cách ngắn nhất, chỉ sử dụng công cụ do python cung cấp:

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

Tất nhiên, nếu bạn không muốn nhập bất cứ thứ gì, bạn luôn có thể viết mã của riêng mình. Một cái gì đó rất cơ bản như thế này:

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

sử dụng nó mà không có dấu phân cách

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.