将不同大小的数据打包到无符号整数列表中 [英] Packing data of different sizes into a list of unsigned ints

查看:126
本文介绍了将不同大小的数据打包到无符号整数列表中的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一组数据,这些数据表示我需要在python中操作的硬件结构.实际结构的大小为4 KB ...我将举一个简单的示例:

I have a set of data that represents a hardware structure that I need to manipulate in python. The real structure is 4 KB in size...I'll just whip up a quick example:

Byte(s)  Value  
0-1      0x0102
2-3      0x0304
4-23     "AStrWith20Characters"
24-63    "WoahThisStringHas40CharactersItIsHuge!!!"
64-71    "Only8Chr"
72-74    0x050607
74       0x08
75-127   0x00 (padding)

这个想法是我将这个结构打包成一个32位Ints的列表,将该列表传递给另一个函数,然后那个函数将整个shebang写入内存.内存写入功能一次可以接受64个字节,因此我必须打两次电话.

The idea is I pack this structure up into a list of 32 bit Ints, pass the list off to another function, and that function then writes the whole shebang out to memory. The Memory Writing function accepts 64 Bytes at a time, so I'd have to make two calls.

因此,对于上面的示例,我需要进行这些调用(我将使用big endian来提高可读性):

So, for the example above, I'd need to make these calls (I'll use big endian for readability):

WrToMemory([0x01020304, 0x41537472, 0x57697468, 0x3230436, 
            0x61726163, 0x74657273, 0x576F6168, 0x5468697, 
            0x53747269, 0x6E674861, 0x73343043, 0x6861726, 
            0x63746572, 0x73497449, 0x73487567, 0x65212121])

WrToMemory([0x4F6E6C79, 0x38436872, 0x05060708, 0x00000000,  
            0x00000000, 0x00000000, 0x00000000, 0x00000000,  
            0x00000000, 0x00000000, 0x00000000, 0x00000000,  
            0x00000000, 0x00000000, 0x00000000, 0x00000000])    

问题是我不知道如何以任何有效的方式打包这些数据.我一直在努力使用structarray,但是或者我在概念上缺少某些东西,或者我只是在使用错误的工具来完成这项工作.

The problem is that I don't know how to pack this data in any kind of efficient way. I have been struggling with using struct and array, but either I am missing something conceptually or I am simply using the wrong tool for the job.

最终,我知道我可以编写一个大型的函数来检查数据类型,进行一堆移位和屏蔽,将ASCII转换为十六进制,并构造所需的数据包.但这似乎……很不讨人喜欢.

Ultimately, I know I can write a big hairy function that checks data types, does a bunch of shifting and masking, converts ASCII to hex, and the constructs data packets I need. But that seems...inelegant.

我认为必须有一种方法来告诉python这是一个两个字节长的数字.将其打包.另一个两个字节的数字,将其附加到最后一个数字之后.现在这是一个包含20个字节的字符串追加,继续直到有64个字节,然后将刚才创建的64个字节的列表转换为由16个无符号整数组成的lsit.

I figure there's got to be a way to tell python "This is a number that is two bytes long. Pack it up. Another two byte number, append it to the last one. Now this is a string, with 20 bytes. Append it. Go on until we have 64 bytes. Then convert the list of 64 bytes we just made into a lsit of 16 unsigned integers.

似乎我应该使用packunpack函数,但是就像我上面说的那样……我肯定缺少一些东西.例如,pack如何处理3个字节的数字?如果您使用HB之类的格式字符串,则pack需要两个参数:

It seems like the pack and unpack functions are what I should be using, but like I said above...I must be missing something. How does pack handle the 3 byte number, for example? If you use a format string like HB, then pack expects two arguments:

>>> pack('HB', 0x050607)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
struct.error: pack requires exactly 2 arguments

而且我不能使用unpack,因为那需要一个字符串,而不是数字.

And I can't use unpack, because that expects a string, not a number.

希望我已经明确了我的问题.任何帮助深表感谢!

Hope I've made my problem clear. Any help is much appreciated!

推荐答案

您使用的是正确的工具,但是您告诉pack编码了2个参数,但只传入了一个.

You are using the right tool, but you told pack to encode 2 arguments, but pass in only one.

字符串HB的意思是:打包两个值,一个打包为无符号的short,另一个打包为无符号的字节.传入两个值即可使用:

The string HB means: pack two values, one as an unsigned short, the other as an unsigned byte. Pass in two values and it works:

>>> pack('HB', 0x0506, 0x07)
'\x06\x05\x07'

只要继续尝试,就可以掌握它.这是示例中使用Big Endian表示法的第一组值:

Just keep experimenting, you'll get the hang of it. Here are the first set of values from your example, in Big Endian notation:

>>> pack('>2H20c40c', 0x0102, 0x0304)
'\x01\x02\x03\x04AStrWith20CharactersWoahThisStringHas40CharactersItIsHuge!!!'

请注意开头的'>',表示信号为字节序.字符串将转换为序列,并作为单个变量应用.通常,将它们附加起来会更容易:

Note the '>' at the start, this signals the endianess. The strings are converted to sequences and applied as individual variables. Generally, it's easier to just append them though:

>>> pack('>2H20c40c', 0x0102, 0x0304) + "AStrWith20Characters" + "WoahThisStringHas40CharactersItIsHuge!!!"
'\x01\x02\x03\x04AStrWith20CharactersWoahThisStringHas40CharactersItIsHuge!!!'

这篇关于将不同大小的数据打包到无符号整数列表中的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆