Python: 解压一个字节串 - 第一个 "part" 的不同长度

Python: Unpack a byte string - various length of first "part"

首先,这是我的第一个问题,所以请耐心等待我;-)

连接到设备时,我收到一个字节字符串,其中包含我想要 unpack/split 的各种数量的“条目”。

结果的第一部分给出了条目总数,然后是所有条目,它们之间用空格分隔。由于每个条目的描述也可能有空格,因此描述的长度也以十六进制提供。

例如,这是一个包含 2 个条目的结果字符串:

2 A Unassigned 5FADD9BF 5FBEB461 1C34 18 FtpC1: xml upload failed 5FB3CE6C 5FBD44BC 3

结果说明:

2 = number of entries (hex)
A = length of description following next (hex)
Description (string)
Timestamp (hex)
Timestamp (hex)
Counter (hex)

18 = length of description
Description
Timestamp
Timestamp
Counter

我假设我应该使用 struct 来解压缩这些字符串并能够处理结果,但老实说,我有点不知道如何开始。有什么建议吗?

提前致谢!

编辑:

data = b'2 A Unassigned 5FADD9BF 5FBEB461 1C34 18 FtpC1: xml upload failed 5FB3CE6C 5FBD44BC 3'
print(repr(data))
b'2 A Unassigned 5FADD9BF 5FBEB461 1C34 18 FtpC1: xml upload failed 5FB3CE6C 5FBD44BC 3'

我对此的看法是拆分字节串,然后遍历跟踪状态的“单词”。

不是完整的程序,但可以这样开始:

s = b'2 A Unassigned 5FADD9BF 5FBEB461 1C34 18 FtpC1: xml upload failed 5FB3CE6C 5FBD44BC 3'

slist = s.split()
state = 'numEntries'
for word in slist:
    #print(word)
    if state == 'numEntries':
        numEntries = int.from_bytes(word, 'little')
        state = 'len'
    elif state == 'len':
        lenDesc = int.from_bytes(word, 'little')
        state = 'desc'
    elif state == 'desc':
        desc = word
        state = 'date'
        print(desc)   

...等等。我不知道这是不是“Pythonic”,Python不是我的“母语”

尝试如下操作

data = b'2 A Unassigned 5FADD9BF 5FBEB461 1C34 18 FtpC1: xml upload failed 5FB3CE6C 5FBD44BC 3'

data += b' '  # pad end with a blank
n, data = data.split(b' ', 1)
n = int(n, 16)
for i in range(n):
    length, data = data.split(b' ', 1)
    length = int(length, 16)
    description = data[:length]
    data = data[length +
                1:]  # skip description and the blank after description
    ts1, ts2, data = data.split(b' ', 2)
    ts1, ts2 = map(lambda s: int(s, 16), (ts1, ts2))
    counter, data = data.split(b' ', 1)
    counter = int(counter, 16)
    print((i, description, ts1, ts2, counter))

希望对您有所帮助

from datetime import datetime

s="2 A Unassigned 5FADD9BF 5FBEB461 1C34 18 FtpC1: xml upload failed 5FB3CE6C 5FBD44BC 3"

number_of_entries=int(s.split(' ')[0],16)
print("Number of entries: ",number_of_entries)
print("=============================")
index_of_first_entry=s.find(' ')+1
s=s[index_of_first_entry:]

for i in range(number_of_entries): 
#if 1==1:
  length_of_description=int(s.split(' ')[0],16)

  #s.replace(' ','#',1).find(' ')+1
  print("length_of_description:",length_of_description)

  index=s.find(' ')+1

  description=s[index:index+length_of_description]
  print("description:",description)

  rest_of_string=s[index+length_of_description+1:]
  timestamp1=int(rest_of_string.split(' ')[0],16)
  date_1 = datetime.fromtimestamp(timestamp1)
  print("timestamp1:",f"{date_1:%Y-%m-%d %H:%M:%S}")

  timestamp2=int(rest_of_string.split(' ')[1],16)
  date_2 = datetime.fromtimestamp(timestamp2)
  print("timestamp2:",f"{date_2:%Y-%m-%d %H:%M:%S}")

  counter=int(rest_of_string.split(' ')[2],16)
  print("counter:",counter)
 
  index_of_next_entry=rest_of_string.replace(' ','#',2).find(' ')+1
  s=rest_of_string[index_of_next_entry:]
  print("-----------------------------")

[结果]:

Number of entries:  2
=============================
length_of_description: 10
description: Unassigned
timestamp1: 2020-11-13 00:56:31
timestamp2: 2020-11-25 19:45:37
counter: 7220
-----------------------------
length_of_description: 24
description: FtpC1: xml upload failed
timestamp1: 2020-11-17 13:21:48
timestamp2: 2020-11-24 17:37:00
counter: 3
-----------------------------