Search code examples
pythonstructbyteunpack

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


First of all, this is my first question here, so please be patience with me ;-)

When connecting to a device, I receive a byte string, which contains a various number of "entries", which I want to unpack/split.

First part of the result gives me the number of entries in total, followed by all entries, which are separated by whitespaces. Since the description of every entry could have whitespaces as well, length of the description is also provided as hex.

For example, this is a result string with 2 entries:

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

Explanation of result:

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

I assume I should use struct to unpack such strings and be able to work with the results, but to be honest, I'm a bit lost on how to start. Any suggestions?

Thank you in advance!

EDIT:

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'

Solution

  • Try something like the following

    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))