简体   繁体   English

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

[英]reorder byte order in hex string (python)

I want to build a small formatter in python giving me back the numeric values embedded in lines of hex strings. 我想在python中构建一个小格式化器,让我回到嵌入在十六进制字符串行中的数值。

It is a central part of my formatter and should be reasonable fast to format more than 100 lines/sec (each line about ~100 chars). 它是格式化程序的核心部分,格式化速度超过100行/秒(每行大约约100个字符)应该是合理的。

The code below should give an example where I'm currently blocked. 下面的代码应该给出一个我目前被阻止的例子。

'data_string_in_orig' shows the given input format. 'data_string_in_orig'显示给定的输入格式。 It has to be byte swapped for each word. 它必须为每个字进行字节交换。 The swap from 'data_string_in_orig' to 'data_string_in_swapped' is needed. 需要从'data_string_in_orig'到'data_string_in_swapped'的交换。 In the end I need the structure access as shown. 最后,我需要结构访问,如图所示。 The expected result is within the comment. 预期结果在评论中。

Thanks in advance Wolfgang R 在此先感谢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)

array.arrays have a byteswap method : array.arrays有一个byteswap方法

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)

The h in array.array('h', x) was chosen because it tells array.array to regard the data in x as an array of 2-byte shorts. harray.array('h', x)选择,因为它告诉array.array都把数据在x为2个字节的短裤的阵列。 The important thing is that each item be regarded as being 2-bytes long. 重要的是每个项目被视为2字节长。 H , which signifies 2-byte unsigned short, works just as well. H ,表示2字节无符号短路,也可以正常工作。

This should do exactly what unutbu's version does, but might be slightly easier to follow for some... 这应该与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)

Basically, unpack 6 shorts big-endian, repack as 6 shorts little-endian. 基本上,打开6短裤big-endian,重新打包为6短裤小端。

Again, same thing that unutbu's code does, and you should use his. 同样,unutbu的代码也是如此,你应该使用他的。

edit Just realized I get to use my favorite Python idiom for this... Don't do this either: 编辑刚刚意识到我会使用我最喜欢的Python成语...不要这样做:

orig = 'b62e000052e366667a66408d'
swap =''.join(sum([(c,d,a,b) for a,b,c,d in zip(*[iter(orig)]*4)], ()))
# '2eb60000e3526666667a8d40'
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))

This is a 32 bit unsigned short swap i achieved with code very much the same as "unutbu's" answer just a little bit easier to understand. 这是一个32位无符号短交换,我使用的代码与“unutbu”的答案非常相似,只是更容易理解。 And technically binascii is not needed for the swap. 交换时不需要技术上的binascii。 Only array.byteswap is needed. 只需要array.byteswap。

The swap from 'data_string_in_orig' to 'data_string_in_swapped' may also be done with comprehensions without using any imports: 从'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'

The comprehension works for swapping byte order in hex strings representing 16-bit words. 该理解适用于交换表示16位字的十六进制字符串中的字节顺序。 Modifying it for a different word-length is trivial. 将其修改为不同的字长是微不足道的。 We can make a general hex digit order swap function also: 我们也可以制作一般的十六进制数字订单交换功能:

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

The input params are: 输入参数是:

d : the input hex string d:输入十六进制字符串

wsz: the word-size in nibbles (eg for 16-bit words wsz=4, for 32-bit words wsz=8) wsz:半字节中的字大小(例如,对于16位字wsz = 4,对于32位字wsz = 8)

gsz: the number of nibbles which stay together (eg for reordering bytes gsz=2, for reordering 16-bit words gsz = 4) gsz:保持在一起的半字节数(例如,重新排序字节gsz = 2,用于重新排序16位字gsz = 4)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM