我想在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)
答案 0 :(得分:14)
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)
选择h
中的array.array('h', x)
是因为它告诉array.array
将x
中的数据视为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)