知道如何在python中解码这些小的endian字节吗?
我正在从一个可移动设备上获取广告数据。我特别感兴趣的是这两个字节:知道如何在python中解码这些小的endian字节吗?,python,hex,bluetooth-lowenergy,unpack,Python,Hex,Bluetooth Lowenergy,Unpack,我正在从一个可移动设备上获取广告数据。我特别感兴趣的是这两个字节: 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' 在设备手册中,该手册可用。它们给出了广告数据的结构。我试着遵循这一点并使用struct.unpack,如下所示: import struc
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'
在设备手册中,该手册可用。它们给出了广告数据的结构。我试着遵循这一点并使用struct.unpack
,如下所示:
import struct
bte = b'\x17d\x0e\x10\x0e\xd7\x02\x1d\x00G\x00U\x01\x00'
struct.unpack('<BBHHHH', bte)
导入结构
bte=b'\x17d\x0e\x10\x0e\xd7\x02\x1d\x00G\x00U\x01\x00'
解包(“在Blue Maestro设备上,我认为他们没有在广告制造商数据中以little-endian格式放置数据
查看您的数据,我希望它如下所示:
导入binascii
从pprint导入pprint
从结构导入解包
pckt=binascii.unexlify('17640e100ed7021d004700550100')
数据={}
数据[“版本”]=解包(“>B”,pckt[0:1])[0]
数据[“batt_lvl”]=拆包(“>B”,pckt[1:2])[0]
数据[“间隔”]=解包(“>H”,pckt[2:4])[0]
数据[“日志计数”]=解包(“>H”,pckt[4:6])[0]
数据[“湿度”]=打开包装(“>h”,pckt[6:8])[0]/10
数据[“露点”]=解包(“>h”,pckt[8:10])[0]/10
数据[“温度”]=打开包装(“>h”,pckt[10:12])[0]/10
pprint(数据)
输出:
{'batt_lvl':100,
“露点”:7.1,
“湿度”:54.1,
“间隔”:3600,
“日志计数”:3799,
“温度”:8.5,
“版本”:23}
您可以一次性打开包装,但必须调整露点湿度和温度值:
unpack('>BBHHhhh', pckt[:12])
# (23, 100, 3600, 3799, 541, 71, 85)
选择单个值时,使用int.from_bytes
功能会更清晰
导入binascii
从pprint导入pprint
pckt=binascii.unexlify('17640e100ed7021d004700550100')
数据={}
data[“version”]=int.from_字节(pckt[0:1],byteorder='big')
数据[“batt_lvl”]=int.from_字节(pckt[1:2],byteorder='big')
data[“interval”]=int.from_字节(pckt[2:4],byteorder='big')
data[“log\u count”]=int.from\u字节(pckt[4:6],byteorder='big')
数据[“湿度”]=int.from_字节(pckt[6:8],byteorder='big',signed=True)/10
数据[“露点”]=int.from_字节(pckt[8:10],byteorder='big',signed=True)/10
数据[“温度”]=int.from_字节(pckt[10:12],byteorder='big',signed=True)/10
pprint(数据)
给出了相同的值:
{'batt_lvl':100,
“露点”:7.1,
“湿度”:54.1,
“间隔”:3600,
“日志计数”:3799,
“温度”:8.5,
“版本”:23}
\x17d
、\x00G
和\x00U
都是两个字节。但是,第二个字节恰好是ASCII值,因此Python在显示时有助于显示字母而不是字节值。
为了证明这一点,我们可以输入字节值,并在输出中看到ASCII值:
>>> b'\x64\x47\x55'
b'dGU'
您可以做一些事情来显示实际的字节值,以帮助调试
使用hexlify:
>>> binascii.hexlify(bte)
b'17640e100ed7021d004700550100'
将字节转换为二进制值列表:
>>> list(bte)
[23, 100, 14, 16, 14, 215, 2, 29, 0, 71, 0, 85, 1, 0]
将其格式化为具有十六进制值的字符串:
>>> [f'{n:02X}' for n in bte]
['17', '64', '0E', '10', '0E', 'D7', '02', '1D', '00', '47', '00', '55', '01', '00']
bbhhh
需要10个字节(1+1+2+2+2),但是b'\x17d\x0e\x10\x0e\xd7\x02\x1d\x00G\x00U\x01\x00'
似乎是14个字节。您的格式字符串是关闭的。顺便说一句,第一个字节是0x17
,第二个字节是0x64
,在ascii世界中也称为:d
。是的,我以前就爱上了它。请注意,\x
后面只有两个数字是部分另一个例子是一个空字节(00
),和“G”
;总共两个字节。你是说:struct.unpack(“非常感谢你,这对我来说非常有效。我不知道int.from_bytes
方法。也正如其他人指出的那样,\x17d
,\x00G
和\x00U
都是你说的两个字节,这让我很困惑。我使用手机上的应用程序进行了一些调试,它显示了温度,我认为是y您可能有一些值被错误标记,但除此之外,这是完美的!