Python使用struct实现3字节整数打包解包及规范报文适配
struct库处理3字节整数的简便实现方案
struct库原生确实没有内置3字节(24位)整数的格式码,结合1字节零填充+3字节包长的报文结构,有两种无额外依赖、完全兼容现有struct开发流程的实现方案:
- 方案一:拆分3字节为struct原生支持的格式段,零额外转换逻辑
3字节整数可以拆分为1字节无符号整数+2字节无符号整数的组合,完全覆盖3字节的数值范围,不需要调用额外的转换方法。
以最常用的大端字节序(网络序)为例,整个报文头的格式串可以定义为>B B H:- 第一个
B对应1字节的填充字段,固定传0即可 - 第二个
B对应3字节包长的最高8位数值 H对应3字节包长的低16位数值
打包时代码示例:
解包时代码示例:import struct packet_length = 1234567 # 实际业务的包长数值 # 生成符合规范的报文头:1字节零填充 + 3字节包长 header = struct.pack( '>B B H', 0, # padding字段固定为0 (packet_length >> 16) & 0xFF, # 包长的最高8位 packet_length & 0xFFFF # 包长的低16位 )
如果报文是小端字节序,只需要调整格式串为# 从接收到的原始数据中取前4字节的报文头 recv_header = recv_data[:4] _, len_high_byte, len_low_two_bytes = struct.unpack('>B B H', recv_header) actual_packet_length = (len_high_byte << 16) + len_low_two_bytes<B H B,对应调整高低字节的拼接逻辑即可。 - 第一个
- 方案二:配合int内置的字节转换方法,简化拆分逻辑
不需要手动做移位计算,直接用整数类型自带的to_bytes/from_bytes方法处理3字节部分,和struct流程无缝衔接:
打包时代码示例:
解包时代码示例:import struct packet_length = 1234567 # 1字节零填充用struct打包 padding = struct.pack('B', 0) # 3字节包长直接转成指定长度的字节串,字节序和报文要求保持一致 length_bytes = packet_length.to_bytes(3, byteorder='big', signed=False) header = padding + length_bytesrecv_header = recv_data[:4] padding_value = struct.unpack('B', recv_header[:1])[0] actual_packet_length = int.from_bytes(recv_header[1:4], byteorder='big', signed=False)
注意事项
- 3字节无符号整数的可表示范围为0~16777215,只要业务包长在这个范围内,两种方案都完全适用
- 不要直接用4字节的整数格式打包后截断字节凑3字节,这种方式很容易因为字节序不匹配出现长度解析错误
- 打包和解包的字节序必须和目标系统的要求完全一致,否则会出现值完全错乱的问题
内容的提问来源于stack exchange,提问作者Swatcat
相关产品推荐
相关产品推荐

