我正在使用的设备的协议以逗号分隔的ASCII格式将UDP数据包发送到服务器(我的Python程序,使用twisted for networking)。为了确认我的应用程序正确收到了数据包,我必须从该数据包的标头中取出几个值,将它们转换为二进制并发回。我有一切设置,但我似乎无法弄清楚二进制部分。
我经历了很多事情,我仍然感到困惑。文档说"二进制"虽然它看起来更像十六进制,因为它说ACK数据包必须以" 0xFE 0x02"开头。
确认格式要求我发送" 0xFE 0x02" + 8个无符号整数(IMEI号,15位)+ 2字节无符号整数(序列号ID)
我如何将我所拥有的ASCII文本值转换为"二进制"?
答案 0 :(得分:2)
首先:
文档说"二进制"虽然它看起来更像十六进制,因为它说ACK数据包必须以" 0xFE 0x02"开始。
嗯,不可能以人类可读的形式打印实际的二进制数据,因此文档通常会给出一个十六进制字节序列。他们可以使用类似bytes
之类的b'\xFE\x02'
字面值,但对于人类读者而言仍然有效十六进制,对吗?
所以,如果他们说"二进制",他们可能意味着"二进制",而十六进制就是他们如何向你显示你需要的二进制字节。
因此,您需要将数字的ASCII表示转换为实际数字,使用int
函数。然后,您需要将pack
转换为8个字节,这与struct
模块一样。
你没有提到你是否需要big-endian或little-endian。由于这听起来像一个网络协议,听起来它不是由微软设计的,我会猜测 big-endian,但你应该知道,而不是猜测。
所以:
imei_string = '1234567890123456789'
imei_number = int(imei_string) # 1234567890123456789
imei_bytes = struct.pack('>Q', imei_number) # b'\x11\x22\x10\xf4\x7d\xe9\x81\x15'
buf = b'\xFE\x02' + imei_bytes + seq_bytes
(你没有说出你应该从哪里得到序列号,但无论它来自哪里,你都以同样的方式pack
,只需使用{{ 1}}而不是>H
。)
如果你实际 需要十六进制字符串而不是二进制字符串,那么你需要确切知道什么格式。 binascii.hexlify
函数为您提供"裸十六进制",每个字节两个字符,无>Q
或其他页眉或页脚。如果你想要不同的东西,那么它取决于你想要什么;没有格式真的那么难。但是,我再次确定你不需要这里的十六进制字符串。
最后一件事:既然你没有指定你的Python版本,我就以与2.6+和3.0+兼容的方式编写了这个版本。如果您需要使用2.5或更早版本,只需将0x
前缀放在b
行的文字上。