在Python中将ASCII数据转换为十六进制/二进制/字节

时间:2015-05-23 04:01:46

标签: python sockets hex

我正在使用的设备的协议以逗号分隔的ASCII格式将UDP数据包发送到服务器(我的Python程序,使用twisted for networking)。为了确认我的应用程序正确收到了数据包,我必须从该数据包的标头中取出几个值,将它们转换为二进制并发回。我有一切设置,但我似乎无法弄清楚二进制部分。

我经历了很多事情,我仍然感到困惑。文档说"二进制"虽然它看起来更像十六进制,因为它说ACK数据包必须以" 0xFE 0x02"开头。

确认格式要求我发送" 0xFE 0x02" + 8个无符号整数(IMEI号,15位)+ 2字节无符号整数(序列号ID)

我如何将我所拥有的ASCII文本值转换为"二进制"?

1 个答案:

答案 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行的文字上。