【问题标题】:Dealing with leading zeros in struct pack/unpack function?处理 struct pack/unpack 函数中的前导零?
【发布时间】:2020-03-13 17:35:12
【问题描述】:

我正在使用 Python 库与传感器进行 ANT+ 无线通信。 通信是通过与一个 4-5 位数字长的 ID 配对来完成的。 在我测试的其中一台设备的 ID 为“00625”之前,一切正常。

跟踪代码,问题的根源是用于对ANT+协议消息的字节进行编码和解码的struct pack/unpack函数。

>>> from struct import *
>>> pack(b'<H', 11977)
'\xc9.'
>>> unpack(b'<H', '\xc9.')
(11977,)
>>> pack(b'<H', 625)
'q\x02'
>>> unpack(b'<H', 'q\x02')
(625,)
>>> pack(b'<H', 00625)
'\x95\x01'
>>> unpack(b'<H', '\x95\x01')
(405,)

所以,当我将 ANT ID 的 11977 或 625 打包然后打开包装时,我得到的正是我打包的东西。

但是,当我打包 ANT ID 00625 然后打开它时,我得到了 405。 不知道我该如何处理这个问题,以便我可以正确打包 00625。

【问题讨论】:

  • 是否可以先将00625打包成字符串'00625',再解包结果?
  • @JYCH 不,扔掉struct.error: cannot convert argument to integer
  • 在 Python 中,十进制整数文字中的前导零是不允许的。您将需要以某种方式将它们剥离。带有00625 文字的代码的来源是什么?
  • 您必须使用 Python 2。带有前导零的整数文字被视为 八进制。在 Python 3 中,这已被删除,但 0o 前缀仍然存在。无论如何,你是如何把这个整数放到你的代码中的?最终这就是问题所在,而不是struct.pack。如果它以字符串形式出现,您应该使用int(),而不是eval(),和raw_input(),而不是input()

标签: python struct endianness pack leading-zero


【解决方案1】:

是的,我使用的是 Python 2,这意味着前导零将使 int 被解释为八进制。 深入研究消息的发送方式,我想通了,而不是传递前导零,我只是传递 '625' 作为 ID,并将包函数参数更改为填充两个填充字节。这样就成功了,只需要添加一个条件,其中任何小于 3 位的 int 都会被填充,如下所示:

>>> from struct import *
>>> pack(b'<H', 625)
'q\x02'
>>> pack(b'<xxH', 625)
'\x00\x00q\x02'

所以我在消息模块上创建了一个条件,根据 ID 的大小使用一个或另一个:

    def deviceNumber(self, device_number):
        if len(str(device_number)) > 3 :
            self._payload[1:3] = pack(b'<H', device_number)
        else :
            self._payload[1:3] = pack(b'<xxH', device_number)

也许有更好的方法,但它正在工作,现在已经足够了!

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-01-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-05-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多