Python 3 构建字节数组

Posted

技术标签:

【中文标题】Python 3 构建字节数组【英文标题】:Python 3 Building an array of bytes 【发布时间】:2011-11-25 05:20:22 【问题描述】:

我需要使用原始二进制数据构建一个 tcp 框架,但我发现的所有关于字节的示例和教程都涉及从字符串转换,这不是我需要的。

简而言之,我只需要构建一个字节数组:

0xA2 0x01 0x02 0x03 0x04

请注意,我来自 C/C++ 世界。

我试过了:

frame = b""
frame += bytes( int('0xA2',16) )
frame += bytes( int('0x01',16) )
frame += bytes( int('0x02',16) )
frame += bytes( int('0x03',16) )
frame += bytes( int('0x04',16) )

然后,将这个帧变量扔给套接字的发送方法,但不能按预期工作,因为帧不包含我想要的...

我知道这是一个关于 Python 的非常基本的问题,所以如果你能指出我正确的方向......

【问题讨论】:

上述代码的问题是bytes 如果给定一个整数而不是一个列表,其行为会非常不同。你应该使用frame += bytes( [ int('0xa2',16) ] ) 我知道您希望(ed)动态地执行此操作,但完全不清楚的是:输入字节来自哪里?您从文本文件中读取十六进制表示法?你在源代码中写下每个字节?你有一个字节数组,你从标准输入读取二进制文件? 【参考方案1】:

使用bytearray

>>> frame = bytearray()
>>> frame.append(0xA2)
>>> frame.append(0x01)
>>> frame.append(0x02)
>>> frame.append(0x03)
>>> frame.append(0x04)
>>> frame
bytearray(b'\xa2\x01\x02\x03\x04')

或者,使用您的代码但修复错误:

frame = b""
frame += b'\xA2' 
frame += b'\x01' 
frame += b'\x02' 
frame += b'\x03'
frame += b'\x04'

【讨论】:

当答案可能无法将其用作解决方案时,您将标签 bytearray 添加到问题中。 @clinisbut 它仍然是相关的——在一般意义上,即使您没有使用 bytearray 类型,您也使用字节数组(概念)。我的答案中的两种方法中的任何一种都可以解决您的问题。 您可以将bytearray替换为bytes,得到大致相同的结果。 bytearray 是一个可变类型,因此它可能比 bytes 更有用用于构建框架。 @agf:这就是你所做的。我只是在告诉 clinis,但 bytearraybytes 之间的区别。但现在我可能需要解释可变类型和不可变类型之间的区别。【参考方案2】:

简单地从标准列表构建框架怎么样?

frame = bytes([0xA2,0x01,0x02,0x03,0x04])

bytes() 构造函数可以从包含int 值的可迭代对象构建字节帧。可迭代是实现迭代器协议的任何东西:列表、迭代器、可迭代对象,例如 range()...所返回的对象。

【讨论】:

【参考方案3】:
frame = b'\xa2\x01\x02\x03\x04'

直到现在才被提及...

【讨论】:

但我需要动态构建框架 这种用于构建字节数组的语法与用于字符串类型的语法相同:您可以使用+ 或其他类似的运算符来动态构建字节数组。【参考方案4】:

agf 的 bytearray 解决方案是可行的,但如果您发现自己需要使用字节以外的数据类型构建更复杂的数据包,您可以尝试struct.pack()。 http://docs.python.org/release/3.1.3/library/struct.html

【讨论】:

【参考方案5】:

这是获取字节数组(列表)的解决方案:

我发现您需要先将 Int 转换为字节,然后再将其传递给 bytes():

bytes(int('0xA2', 16).to_bytes(1, "big"))

然后从字节创建一个列表:

list(frame)

所以你的代码应该是这样的:

frame = b""
frame += bytes(int('0xA2', 16).to_bytes(1, "big"))
frame += bytes(int('0x01', 16).to_bytes(1, "big"))
frame += bytes(int('0x02', 16).to_bytes(1, "big"))
frame += bytes(int('0x03', 16).to_bytes(1, "big"))
frame += bytes(int('0x04', 16).to_bytes(1, "big"))
bytesList = list(frame)

问题是字节数​​组(列表)。您接受了一个没有说明如何获取列表的答案,所以我不确定这是否真的是您需要的。

【讨论】:

【参考方案6】:

我认为 Scapy 就是您要找的东西。

http://www.secdev.org/projects/scapy/

您可以使用它构建和发送帧(数据包)

【讨论】:

谢谢,但我更感兴趣的是学习如何去做;) 好吧,scapy 只是一个很好的工具,可以用于一般的网络和数据包项目。我认为您正在寻找的是这样的: > >>> from struct import * > >>>>>> packet = pack('Bbbbb',162,1,2,3,4,) > >>> packet > '\xa2\x01\x02\x03\x04' 第二条评论只是python,pack the data packet = pack('Bbbbb',162,1,2,3,4,) 然后你就有了你的框架。 Python 没有数组,只有列表。有关更多信息,请参阅有关结构 docs.python.org/library/struct.html 的文档 @Venec Python 2.6+ 实际上有一个 bytearray 类型。 Scapy 在这方面太过分了。

以上是关于Python 3 构建字节数组的主要内容,如果未能解决你的问题,请参考以下文章

如何从 Python 3 中的字节数组中的特定位中提取值?

C# - 我可以使用数组初始化器从另一个字节数组中构建一个字节数组吗?

Python:如何从 4 字节字节数组中获取 4 字节大小的整数?

将字节数组转换为 tagVARIANT 数组

在 Python 3 中将二进制字符串转换为字节数组

如何在python 3中有效地将原始字节写入numpy数组数据