我有一个数字列表,我想作为二进制数据发送到套接字连接。
举个例子,我从以下列表开始:
data = [2,25,0,0,ALPHA,0,23,18,188]
在上面的列表中, ALPHA 可以是1到999之间的任何值。最初,我使用
将其转换为字符串 hexdata = ''.join([chr(item) for item in data])
因此,如果ALPHA为101,则返回以下字符串:
>>> data = [2,25,0,0,101,0,23,18,188]
>>> hexdata = ''.join([chr(item) for item in data])
>>> hexdata
'\x02\x19\x00\x00e\x00\x17\x12\xbc'
这很好用,'\ x02 \ x19 \ x00 \ x00e \ x00 \ x17 \ x12 \ xbc'是我需要发送的字符串。
但是,这对于超过255的ALPHA值不起作用,因为它超出了chr语句的范围。如果例如ALPHA是999,那么我想得到以下字符串:
data = [2,25,0,0,999,0,23,18,188]
hexdata = '\x02\x19\x00\x03\xed\x00\x17\x12\xbc'
我一直在查看struct.pack()上的文档,但看不出如何用它来实现上面的字符串。 ALPHA是列表中唯一的变量。
非常感谢任何帮助。
编辑1
你想要什么行为?什么 256到65535之间需要2个字节 代表。你想打开它吗? 另一边?请更新帖子 与你的意图。 - gahooa 1分钟前
这是正确的,因为999超过了256个阈值,它由两个字节表示:
data = [2,25,0,0,999,0,23,18,188]
hexdata = '\x02\x19\x00**\x03\xed**\x00\x17\x12\xbc'
这有意义吗?
就解包而言,我只是将这些数据发送到套接字上,我将接收数据但已经处理好了。
编辑2
我发出的字符串总是固定长度。 为简单起见,我认为最好将列表表示如下:
ALPHA = 101
data = [25,alpha1,alpha2,1]
hexdata = '\x19\x00e\x01'
ALPHA = 301
data = [25,alpha1,alpha2,1]
hexdata = 'x19\x01\x2d\x01'
正如您在hexdata字符串中看到的那样,然后变为:\ x01 \ x2d \
如果ALPHA< 256,alpha1 = 0.
答案 0 :(得分:9)
如果是< ALPHA,您希望为ALPHA发送一个字节。 256,但如果> = 256,则为两个字节?这看起来很奇怪 - 接收器怎么知道是哪种情况...... ???
但是,如果这是你想要的,那么
x = struct.pack(4*'B' + 'HB'[ALPHA<256] + 4*'B', *data)
是实现这一目标的一种方式。
答案 1 :(得分:5)
如果您事先知道数据和ALPHA位置,最好使用struct.pack,并为该位置设置一个大端短路,并省略可能被覆盖的0:
def output(ALPHA):
data = [2,25,0,ALPHA,0,23,18,188]
format = ">BBBHBBBB"
return struct.pack(format, *data)
output(101) # result: '\x02\x19\x00\x00e\x00\x17\x12\xbc'
output(999) # result: '\x02\x19\x00\x03\xe7\x00\x17\x12\xbc'
答案 2 :(得分:3)
您可以使用python array
import array
a = array.array('i')
a.extend([2,25,0,0,101,0,23,18,188])
output = a.tostring()
答案 3 :(得分:1)
字节的值不能超过255,因此当ALPHA超过255时,您将不得不将其拆分为两个字节。这可以这样做:
high, low = divmod(ALPHA, 255)
然后你可以将高点和低点粘贴到值列表中。
还有其他变体,比如使用bytearray(在2.6中)或struct.pack等,但最后你必须以某种方式将这两个字节转换为两个字节。
答案 4 :(得分:0)
如果是&lt; ALPHA,您希望为ALPHA发送一个字节。 256,但如果&gt; = 256,则为两个字节?
另一种(也许更通用的)方式是:
x = reduce(lambda x, y: x + y, map(lambda x: struct.pack('B', x), data))