我有一个十六进制字符串(从十六进制转储文件组合在一起),需要以大端顺序解析以读取各个位。
以下是消息结构的一些示例,其中每条消息的预期值来自十六进制字符串 dd8d9880。
留言 | 大小(以位为单位) | 起始字节 | 开始位 | 期望值 |
---|---|---|---|---|
留言1 | 8 | 0 | 0 | 221 |
消息2 | 4 | 1 | 0 | 13 |
留言3 | 4 | 1 | 4 | 8 |
消息4 | 1 | 2 | 0 | 0 |
留言5 | 1 | 2 | 1 | 0 |
留言6 | 1 | 2 | 2 | 0 |
消息7 | 3 | 2 | 3 | 3 |
如何解码此类十六进制字符串以获取这些值。我正在使用 python struct 模块,但发现很难理解字节序并相应地进行转换。
如评论中所述,数据以字节为单位以小端存储(最低有效位 (LSB) 为位 0)以实现所需的解码。
|.|字节1 |字节2 |字节3 |字节4 | |-|--------|--------|--------|--------| |位位置|76543210|7654 3210|76 543 2 1 0|76543210| |位|11011101 (0xDD)|1000 1101 (0x8D)|10 011 0 0 0 (0x98)|10000000 (0x80)| 下面是一个
ctypes
示例:
import ctypes as ct
class Message(ct.Structure):
_fields_ = (
('m1', ct.c_uint8), # bits 0-7 of byte 1
('m2', ct.c_uint8, 4), # bits 0-3 of byte 2
('m3', ct.c_uint8, 4), # bits 4-7 of byte 2
('m4', ct.c_uint8, 1), # bit 0 of byte 3
('m5', ct.c_uint8, 1), # bit 1 of byte 3
('m6', ct.c_uint8, 1), # bit 2 of byte 3
('m7', ct.c_uint8, 3), # bits 3-5 of byte 3
# Note that byte 3 bits 6-7 as are unused and this structure has a size of 3 bytes.
# Uncomment below if you want the message to be 4 bytes and have access to remaining bits.
# ('m8', ct.c_uint8, 2), # bits 6-7 of byte 3
# ('m9', ct.c_uint8), # Added byte to make structure 4 bytes if you care.
)
def __repr__(self):
# Makes a nice debug representation of Message when printed.
return (
f'Message(m1={self.m1}, m2={self.m2}, m3={self.m3}, m4={self.m4}, m5={self.m5}, m6={self.m6}, m7={self.m7}'
# Uncomment below to print unused bits.
# f', m8={self.m8}, m9={self.m9}'
f')'
)
# Create a message with the 4-byte hexadecimal string example.
m = Message.from_buffer_copy(bytes.fromhex('dd8d9880'))
print(m)
输出:
Message(m1=221, m2=13, m3=8, m4=0, m5=0, m6=0, m7=3)
为未使用的位添加 m8/m9 的输出:
Message(m1=221, m2=13, m3=8, m4=0, m5=0, m6=0, m7=3, m8=2, m9=128)