2008-10-14 72 views
6

Sử dụng PHP pack() chức năng, tôi đã chuyển đổi một chuỗi thành một đại diện hex nhị phân:Làm cách nào để giải nén dữ liệu được định dạng hex nhị phân trong Python?

$string = md5(time); // 32 character length 
$packed = pack('H*', $string); 

H * định dạng có nghĩa là "Hex chuỗi, cao nibble đầu tiên".

Để giải nén tệp này bằng PHP, tôi chỉ cần sử dụng hàm unpack() với cờ định dạng H *.

Làm cách nào để giải nén dữ liệu này bằng Python?

+0

bạn có thuật ngữ của bạn bị nhầm lẫn khủng khiếp. – hop

+0

@hop: Khác với "hex nhị phân", tất cả đều OK. Chỉ có một chút khác biệt về từ vựng chéo. Nó làm tôi bối rối lúc đầu cho đến khi tôi đọc định nghĩa của gói PHP(), nhưng nó chỉ là vấn đề của các thuật ngữ khác nhau được sử dụng. – Brian

Trả lời

12

Có một cách dễ dàng để làm điều này với các mô-đun binascii:

>>> import binascii 
>>> print binascii.hexlify("ABCZ") 
'4142435a' 

Trừ khi tôi hiểu nhầm điều gì đó về yêu cầu đặt trước (cao cấp trước tiên là mặc định), điều đó phải đủ hoàn toàn!

Hơn nữa, đối tượng hashlib.md5 của Python có phương thức hexdigest() để tự động chuyển đổi thông báo MD5 thành chuỗi hex ASCII, do đó phương pháp này thậm chí không cần thiết cho việc phân tích MD5. Hy vọng rằng sẽ giúp.

8

Trong Python, bạn sử dụng mô-đun struct cho việc này.

>>> from struct import * 
>>> pack('hhl', 1, 2, 3) 
'\x00\x01\x00\x02\x00\x00\x00\x03' 
>>> unpack('hhl', '\x00\x01\x00\x02\x00\x00\x00\x03') 
(1, 2, 3) 
>>> calcsize('hhl') 
8 

HTH

+3

Lưu ý: "h" có nghĩa là một cái gì đó khác trong cấu trúc hơn "nibble được mã hóa dưới dạng hex" - nó đề cập đến một số nguyên 16 bit. – Brian

+0

Như trong sHort int. – XTL

11

Không có tương ứng "hex nibble" mã cho struct.pack, vì vậy bạn sẽ hoặc là cần phải tự đóng gói vào byte đầu tiên, như:

hex_string = 'abcdef12' 

hexdigits = [int(x, 16) for x in hex_string] 
data = ''.join(struct.pack('B', (high <<4) + low) 
       for high, low in zip(hexdigits[::2], hexdigits[1::2])) 

Hoặc tốt hơn, bạn chỉ có thể sử dụng codec hex. I E.

>>> data = hex_string.decode('hex') 
>>> data 
'\xab\xcd\xef\x12' 

Để giải nén, bạn có thể mã hóa kết quả lại để hex tương tự

>>> data.encode('hex') 
'abcdef12' 

Tuy nhiên, lưu ý rằng ví dụ của bạn, có lẽ không cần phải lấy khứ hồi thông qua một đại diện hex ở tất cả khi mã hóa. Chỉ cần sử dụng trực tiếp thông tin nhị phân md5. I E.

>>> x = md5.md5('some string') 
>>> x.digest() 
'Z\xc7I\xfb\xee\xc96\x07\xfc(\xd6f\xbe\x85\xe7:' 

Điều này tương đương với đại diện gói() của bạn. Để có được đại diện hex, sử dụng phương pháp giải nén tương tự trên:

>>> x.digest().decode('hex') 
'acbd18db4cc2f85cedef654fccc4a4d8' 
>>> x.hexdigest() 
'acbd18db4cc2f85cedef654fccc4a4d8' 

[Chỉnh sửa]: Cập nhật để sử dụng phương pháp tốt hơn (hex codec)

+1

Trong phiên bản đầu tiên, có điều gì đặc biệt để nhập để sử dụng câu lệnh nhóm không? –

+0

@Leandro: Rất tiếc - nhóm() là một hàm trong thư viện của riêng tôi (ngắt chuỗi thành các nhóm gồm N ký tự). Tôi đã cập nhật mã để chỉ sử dụng một lát để tránh hàm không xác định. – Brian

Các vấn đề liên quan