以十六进制字符串(python)重新排序字节顺序

时间:2012-10-31 10:10:53

标签: python string hex swap python-2.x

我想在python中构建一个小格式化程序,让我返回数字 嵌入在十六进制字符串行中的值。

它是我格式化程序的核心部分,应该快速合理 格式超过100行/秒(每行约100个字符)。

下面的代码应该举例说明我目前被阻止了。

'data_string_in_orig'显示给定的输入格式。它一定要是 每个字交换一个字节。从'data_string_in_orig'交换到 'data_string_in_swapped'是必需的。最后我需要结构 访问如图所示。预期结果在评论范围内。

提前致谢 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)

4 个答案:

答案 0 :(得分:14)

array.arraysbyteswap 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)

选择h中的array.array('h', x)是因为它告诉array.arrayx中的数据视为2字节短路数组。重要的是每个项目被视为2字节长。表示2字节无符号短整数的H也可以正常工作。

答案 1 :(得分:7)

这应该与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个短裤big-endian,重新打包为6短裤小端。

同样,unutbu的代码也是如此,你应该使用他的。

编辑刚刚意识到我会使用我最喜欢的Python成语......不要这样做:

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

答案 2 :(得分: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位无符号短交换,我使用的代码与&#34; unutbu&#39;#34;非常相同。回答只是更容易理解。交换时不需要技术上的binascii。只需要array.byteswap。

答案 3 :(得分: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)]])

输入参数是:

d:输入十六进制字符串

wsz:半字节中的字大小(例如,对于32位字wsz = 8,16位字wsz = 4)

gsz:保持在一起的半字节数(例如重新排序字节gsz = 2,重新排序16位字gsz = 4)