2012-10-31 77 views
7

Tôi muốn xây dựng một trình định dạng nhỏ trong python cho tôi trở lại các giá trị số được nhúng trong các dòng của chuỗi hex.sắp xếp lại thứ tự byte trong chuỗi hex (python)

Đây là phần trung tâm của trình định dạng của tôi và phải hợp lý với định dạng nhiều hơn 100 dòng/giây (mỗi dòng khoảng ~ 100 ký tự).

Mã bên dưới sẽ đưa ra ví dụ nơi tôi hiện bị chặn.

'data_string_in_orig' hiển thị định dạng nhập đã cho. Nó phải là byte hoán đổi cho mỗi từ. Hoán đổi từ 'data_string_in_orig' thành 'data_string_in_swapped' là cần thiết. Cuối cùng tôi cần cấu trúc truy cập như được hiển thị. Kết quả mong đợi nằm trong nhận xét.

Cảm ơn trước Wolfgang R

#!/usr/bin/python 

import binascii 
import struct 

## 'uint32 double' 
data_string_in_orig = 'b62e000052e366667a66408d' 
data_string_in_swapped = '2eb60000e3526666667a8d40' 
print data_string_in_orig 

packed_data = binascii.unhexlify(data_string_in_swapped) 
s = struct.Struct('<Id') 
unpacked_data = s.unpack_from(packed_data, 0) 
print 'Unpacked Values:', unpacked_data 

## Unpacked Values: (46638, 943.29999999943209) 

exit(0) 

Trả lời

13

array.arrays có một byteswap method:

import binascii 
import struct 
import array 
x = binascii.unhexlify('b62e000052e366667a66408d') 
y = array.array('h', x) 
y.byteswap() 
s = struct.Struct('<Id') 
print(s.unpack_from(y)) 

# (46638, 943.2999999994321) 

Các h trong array.array('h', x) được chọn vì nó nói array.array để xem các dữ liệu trong x như một mảng của 2 quần đùi. Điều quan trọng là mỗi mục được coi là dài 2 byte. H, có nghĩa là không có ký hiệu ngắn 2 byte, cũng hoạt động tốt.

+0

'array.byteswap'. Ngọt. Đoán tôi sẽ tiếp tục và không đăng bài giải nén nhỏ gọn về giải pháp cuối cùng/giải pháp nhỏ gọn của kludgy mà tôi đã nấu ... – Triptych

+0

Hãy tiếp tục và đăng nó! Có nhiều cách để giải quyết vấn đề có thể hữu ích. – unutbu

+1

Cảm ơn, điều này rất nhanh và hoàn hảo đối với tôi. Bằng cách này 100k dòng trong 5 giây. –

6

này nên thực hiện chính xác những gì phiên bản unutbu của có, nhưng có thể là một chút dễ dàng hơn để làm theo cho một số ...

from binascii import unhexlify 
from struct import pack, unpack 
orig = unhexlify('b62e000052e366667a66408d') 
swapped = pack('<6h', *unpack('>6h', orig)) 
print unpack('<Id', swapped) 

# (46638, 943.2999999994321) 

Về cơ bản, giải nén 6 quần short lớn về cuối nhỏ, đóng gói lại như 6 quần short về cuối nhỏ.

Một lần nữa, điều tương tự mà mã của unutbu thực hiện và bạn nên sử dụng mã của mình.

chỉnh sửa Chỉ cần nhận ra tôi nhận được để sử dụng thành ngữ Python yêu thích của tôi cho điều này ... Đừng làm điều này một trong hai:

orig = 'b62e000052e366667a66408d' 
swap =''.join(sum([(c,d,a,b) for a,b,c,d in zip(*[iter(orig)]*4)],())) 
# '2eb60000e3526666667a8d40' 
0
import binascii, tkinter, array 
from tkinter import * 

infile_read = filedialog.askopenfilename() 

with open(infile, 'rb') as infile_: 
    infile_read = infile_.read() 

x = (infile_read) 
y = array.array('l', x) 
y.byteswap() 
swapped = (binascii.hexlify(y)) 

Đây là một 32 bit trao đổi ngắn unsigned tôi đạt được với mã rất giống với câu trả lời "unutbu" chỉ là một chút dễ hiểu hơn. Và kỹ thuật binascii là không cần thiết cho việc trao đổi. Chỉ array.byteswap là cần thiết.

0

Các hoán đổi từ 'data_string_in_orig' thành 'data_string_in_swapped' cũng có thể được thực hiện với comprehensions mà không sử dụng bất kỳ nhập khẩu:

>>> d = 'b62e000052e366667a66408d' 
>>> "".join([m[2:4]+m[0:2] for m in [d[i:i+4] for i in range(0,len(d),4)]]) 
'2eb60000e3526666667a8d40' 

Các hiểu biết làm việc cho trao đổi thứ tự byte trong chuỗi hex đại diện từ 16-bit. Sửa đổi nó cho một chiều dài từ khác nhau là tầm thường. Chúng ta có thể làm cho một hex chữ số chức năng để trao đổi nói chung cũng:

def swap_order(d, wsz=4, gsz=2): 
    return "".join(["".join([m[i:i+gsz] for i in range(wsz-gsz,-gsz,-gsz)]) for m in [d[i:i+wsz] for i in range(0,len(d),wsz)]]) 

Các params đầu vào là:

d: chuỗi hex đầu vào

WSZ: từ kích thước trong Nibbles (e.g cho các từ 16 bit wsz = 4, đối với các từ 32 bit wsz = 8)

gsz: số lượng các nibbles ở cùng nhau (ví dụ để sắp xếp lại byte gsz = 2, để sắp xếp lại các từ 16 bit gsz = 4)

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