如何解释十六进制到无符号长整数(20位整数,12位小数,模20位)

2024-09-30 22:20:49 发布

您现在位置:Python中文网/ 问答频道 /正文

我正在从一个传感器获取UDP数据包形式的数据。手册提供了这些数据包的格式,但是我很难理解如何解释时间戳。它被描述为长度为4字节的无符号长(例如“a07245ba”),应该被解释为20位整数和12位小数。我也被包含的“模20位”信息搞糊涂了。你知道吗

如何正确解释这些时间戳?你知道吗

我尝试过简单地用Python的“int('str',16)”函数(例如int('a0724',16)和int('5ba',16))将数字分为两个部分,然后将这两个部分与十进制组合起来(例如“657188.1466秒”)。 这似乎给了我时间戳的正确单位(秒),因为我记录了约10秒的数据,第一个和最后一个时间戳相隔10秒。然而,数字的分数部分似乎不正确。当我绘制数据时,时间戳会意外地前后跳跃,这使我相信我对时间戳的解释是错误的。你知道吗

另外,我解释的时间戳与任何期望值都不相关。手册上说,应该以开机后的秒数或2010年1月1日后的秒数返回。经检查,这两种情况似乎都不是这样。你知道吗

所以时间戳意外地跳到了726162.71秒,然后又跳回到了726126.125秒。前四个字节是时间戳:

datasample = np.array(['b1491fda 00001017 00040a88 00000000 0a 02 00c24d18 0076dd10 fd13fe3c 0032d8ce 0222c71a 01f0f0fa',
       'b1492010 00001018 00040a88 00000000 0a 02 00c249aa 0076dbee fd148e86 0032dc34 02235336 01f0f3c8',
       'b1492047 00001019 00040a88 00000000 0a 02 00c2463c 0076dacc fd151ed0 0032df9a 0223df52 01f0f696',
       'b149207d 0000101a 00040a88 00000000 0a 02 00c248d0 0076da0a fd13fff4 003265b8 02239a24 01f0f3e0',
       'b14920b4 0000101b 00040a88 00000000 0a 02 00c248d0 0076da0a fd13fff4 003265b8 02239a24 01f0f3e0',
       'b14920eb 0000101c 00040a88 00000000 0a 02 00c1eed0 0076a812 fd148d00 0032b896 022396fe 01f0b4ac'],
      dtype='|S98')

timesample = np.array([726161.4058, 726162.16, 726162.71, 726162.125, 726162.18, 726162.235 ])

以下是相隔约10秒的两个数据包的示例:

datasample10 = np.array(['b1a2f9ea 000012ea 00040a88 00000000 0a 02 00c230d4 007671a6 fd1c2538 002b512e 021b9f7c 01f14944',
           'b1a39a8e 000015db 00040a88 00000000 0a 02 00c1d26c 0076b032 fd1c3554 002d51b2 021bd5a0 01f0cd92'],
          dtype='|S98')

timesample10 = np.array([727599.2538, 727609.2702])

Tags: 数据字节np时间数字手册传感器数据包
1条回答
网友
1楼 · 发布于 2024-09-30 22:20:49

12位可以表示2**12不同的数字。它可以表示从02**12 - 1(即4095)的整数。 如果我们取整数的十进制字符串表示法,直接把它转换成一秒钟的小数部分, 那么我们只能表示从00.4096的分数秒。这似乎不对。你知道吗

要在01之间均匀分布分数部分,我们需要除以4096

import numpy as np
datasample = np.array(['b1491fda 00001017 00040a88 00000000 0a 02 00c24d18 0076dd10 fd13fe3c 0032d8ce 0222c71a 01f0f0fa',
                       'b1492010 00001018 00040a88 00000000 0a 02 00c249aa 0076dbee fd148e86 0032dc34 02235336 01f0f3c8',
                       'b1492047 00001019 00040a88 00000000 0a 02 00c2463c 0076dacc fd151ed0 0032df9a 0223df52 01f0f696',
                       'b149207d 0000101a 00040a88 00000000 0a 02 00c248d0 0076da0a fd13fff4 003265b8 02239a24 01f0f3e0',
                       'b14920b4 0000101b 00040a88 00000000 0a 02 00c248d0 0076da0a fd13fff4 003265b8 02239a24 01f0f3e0',
                       'b14920eb 0000101c 00040a88 00000000 0a 02 00c1eed0 0076a812 fd148d00 0032b896 022396fe 01f0b4ac'],
                      dtype='|S98')
print(np.array([int(row[:8],16)  for row in datasample]) / 2**12)

收益率

[726161.99072266 726162.00390625 726162.01733398 726162.03051758 726162.04394531 726162.05737305]

这有一个很好的特性,时间戳都在增加:

result = (np.array([int(row[:8],16)  for row in datasample]) / 2**12)
print(np.diff(result))
# [0.01318359 0.01342773 0.01318359 0.01342773 0.01342773]

datasample10映射到相隔约10秒的时间戳:

datasample10 = np.array(['b1a2f9ea 000012ea 00040a88 00000000 0a 02 00c230d4 007671a6 fd1c2538 002b512e 021b9f7c 01f14944',
           'b1a39a8e 000015db 00040a88 00000000 0a 02 00c1d26c 0076b032 fd1c3554 002d51b2 021bd5a0 01f0cd92'],
          dtype='|S98')

result = (np.array([int(row[:8],16)  for row in datasample10]) / 2**12)
print(np.diff(result))
# [10.04003906]

我不知道这些十六进制字符串应该如何解释为秒 自电源开启或2010年1月1日起。 如果它们代表的是电源开启后的秒数,那么你发布的数据可能就在那之后不久, 那么使数字大小合理的一种方法是取整数模2**20,即模20位:

result = (np.array([int(row[:8],16)  for row in datasample]) % 2**20 / 2**12) 
print(result)
# [145.99072266 146.00390625 146.01733398 146.03051758 146.04394531 146.05737305]

但如果这是正确的,那么在原来的32位中,只有最右边的20位 使用12位表示小数部分,8位表示整数部分 秒。这意味着在值循环回0之前,最大时间戳只能是256。 这似乎相当有限,所以我不相信这是正确的方式来解释“模20位”。你知道吗

另一方面,如果时间戳表示自2010-1-1以来的秒数,那么我们应该期望整数 301000000人:

import datetime as DT
print((DT.datetime.now() - DT.datetime(2010,1,1)).total_seconds())
# 301151491.085063

我还没猜到从datesample到时间戳的映射范围是3.01亿 它保持了单调性和已知的10秒间隔。你知道吗

Well, we could just add 301 million to our current formula, but that would be totally contrived...

相关问题 更多 >