微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

知道如何在 python 中解码这些小端字节吗?

如何解决知道如何在 python 中解码这些小端字节吗?

我正在从 BLE 设备中获取广告数据。我特别对这两个字节感兴趣:

b'\x17d\x0e\x10\x0e\xd7\x02\x1d\x00G\x00U\x01\x00'
b'\x02\xad\x02\x8d\x00\x9b\x00\x0e\x01\xf6\x01\xad\x00\xcf\x00V\x01-\x01+\x00\x00\x00\x00\x00'

在设备手册中,可用 here。他们给出了广告数据的结构。我试图遵循这一点并使用 struct.unpack 如下所示:

import struct

bte = b'\x17d\x0e\x10\x0e\xd7\x02\x1d\x00G\x00U\x01\x00'
struct.unpack('<BBHHHH',bte)

但是,我收到此错误“解包需要 10 个字节的缓冲区”。我认为这与第一个字节 \x17d\ 有关,因为当您有一个超过两个字符的字节时,struct.unpack 总是会返回此错误。还有字节 \x00G\\x00U\ 因为我不确定 U 和 G 是什么意思。此外,此字节的长度为 11,而格式为 <BBHHHH 的字节应仅为 10。

任何帮助将不胜感激。

解决方法

在 Blue Maestro 设备上,我认为他们不会将数据以小端格式放入广告制造商数据中。

查看您的数据,我希望它类似于以下内容:

import binascii
from pprint import pprint
from struct import unpack

pckt = binascii.unhexlify('17640e100ed7021d004700550100')
data = {}

data["version"] = unpack(">B",pckt[0:1])[0]
data["batt_lvl"] = unpack(">B",pckt[1:2])[0]
data["interval"] = unpack(">H",pckt[2:4])[0]
data["log_count"] = unpack(">H",pckt[4:6])[0]
data["humidity"] = unpack(">h",pckt[6:8])[0] / 10
data["dew_point"] = unpack(">h",pckt[8:10])[0] / 10
data["temperature"] = unpack(">h",pckt[10:12])[0] / 10
pprint(data)

给出输出:

{'batt_lvl': 100,'dew_point': 7.1,'humidity': 54.1,'interval': 3600,'log_count': 3799,'temperature': 8.5,'version': 23}

您可以一次性打开包装,但您必须调整露点湿度和温度值:

unpack('>BBHHhhh',pckt[:12])
# (23,100,3600,3799,541,71,85)

在挑选单个值时,使用 int.from_bytes 功能会更清晰。

import binascii
from pprint import pprint

pckt = binascii.unhexlify('17640e100ed7021d004700550100')
data = {}

data["version"] = int.from_bytes(pckt[0:1],byteorder='big')
data["batt_lvl"] = int.from_bytes(pckt[1:2],byteorder='big')
data["interval"] = int.from_bytes(pckt[2:4],byteorder='big')
data["log_count"] = int.from_bytes(pckt[4:6],byteorder='big')
data["humidity"] = int.from_bytes(pckt[6:8],byteorder='big',signed=True) / 10
data["dew_point"] = int.from_bytes(pckt[8:10],signed=True) / 10
data["temperature"] = int.from_bytes(pckt[10:12],signed=True) / 10
pprint(data)

给出相同的值:

{'batt_lvl': 100,'version': 23}

\x17d\x00G\x00U 都是两个字节。然而,第二个字节恰好是 ASCII 值,因此 Python 在显示时会显示字母而不是字节值。 为了证明这一点,我们可以输入字节值并在输出中查看 ASCII 值:

>>> b'\x64\x47\x55'
b'dGU'

您可以执行一些操作来显示实际字节值以帮助调试。

使用十六进制:

>>> binascii.hexlify(bte)
b'17640e100ed7021d004700550100'

将字节转换为一个 denary 值列表:

>>> list(bte)
[23,14,16,215,2,29,85,1,0]

将其格式化为带有十六进制值的字符串:

>>> [f'{n:02X}' for n in bte]
['17','64','0E','10','D7','02','1D','00','47','55','01','00']

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。