2012-10-31 21 views
7

我想在python中建立一個小格式化程序,讓我回到嵌入在十六進制字符串行中的數值 值。以十六進制字符串重新排序字節順序(python)

它是我的格式化程序的中心部分,應該合理快速到 格式超過100行/秒(每行約100個字符)。

下面的代碼應該舉例說明我目前被阻止的示例。

'data_string_in_orig'顯示給定的輸入格式。必須爲每個單詞交換 字節。需要從'data_string_in_orig'交換到 'data_string_in_swapped'。最後我需要如圖所示的結構 訪問。預期的結果在評論中。

預先感謝 沃爾夫岡ř

#!/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) 

回答

13

array.arrays具有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) 

array.array('h', x)h被選擇,因爲它告訴array.array都把數據x作爲2數組短字。重要的是每個項目都被認爲是2個字節長。表示2字節無符號短的H也適用。

+0

'array.byteswap'。甜。猜猜我會繼續前進,而不是發佈kludgy解壓我已經做飯的大端/重新包裝的小端解決方案... – Triptych

+0

繼續前進併發布!有多種解決問題的方法可能會有用。 – unutbu

+1

謝謝,這對我來說是快速和完美的。順便說一下,在5秒內100k線。 –

6

這應該怎麼做unutbu的版本做,但可能會稍微容易遵循一些...

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) 

基本上,解開6個短褲大端,重新包裝爲6個短褲小端。

同樣,unutbu的代碼也是這樣,你應該使用他的代碼。

編輯剛剛意識到我可以用我最喜歡的Python的成語這個......別這樣做可以:

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

這是一個32位無符號短掉我實現代碼與「unutbu的」答案非常相似,只是更容易理解。交換不需要技術上的binascii。只需要array.byteswap。

0

從「data_string_in_orig」到「data_string_in_swapped」的交換也可以與內涵做到不使用任何進口:

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

的理解適用於在代表16位字十六進制字符串交換字節順序。修改它爲一個不同的字長是微不足道的。我們可以做一個普通十六進制數字順序交換功能也:

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

輸入PARAMS是:

d:輸入十六進制字符串

WSZ:字大小的半字節(E。g對於16位字wsz = 4,對於32位字wsz = 8)

gsz:保持在一起的半字節的數量(例如,用於重新排序字節gsz = 2,用於重新排序16位字gsz = 4 )

相關問題