Python解析变长结构体
最近接到一个需求,需要使用 Python 解析 C 来的数据包,而数据包中的格式是通过如下结构体定义的:
typedef struct msg_t
{
int oid;
int msg_len;
char msg_data[0];
}MSG_T;
其中的 msg_data
字符串的长度是由 msg_len
给出的,因此需要首先解析出 msg_len
的数值,再读取 msg_len
的内容。
在 Python 中可以通过 struct 模块完成这一操作,针对以上数据结构的 python 解析代码如下:
OID = 0
msgLen = 0
msgData = ""
sFormat = ""
OID, msgLen = struct.unpack('II', syncMsg[0:8])
sFormat = 'II' + str(msgLen) + 's'
OID, msgLen, msgData = struct.unpack(sFormat, syncMsg)
msgData = msgData.decode()
#print("OID: ", OID, "nMsgLen: ", msgLen, "nMsgData: ", msgData.decode())
代码最核心之处在于 unpack
时的单引号部分,其中 I
代表 Int
, 128s
则代表长度为 128 的字符串。在这里首先解析长度,再拼接处数据格式,进而解析。
struct 中支持的格式如下表:
Format |
C Type |
Python |
字节数 |
---|---|---|---|
x |
pad byte |
no value |
1 |
c |
char |
string of length 1 |
1 |
b |
signed char |
integer |
1 |
B |
unsigned char |
integer |
1 |
? |
_Bool |
bool |
1 |
h |
short |
integer |
2 |
H |
unsigned short |
integer |
2 |
i |
int |
integer |
4 |
I (大写的 i) |
unsigned int |
integer or long |
4 |
l (小写的 L) |
long |
integer |
4 |
L |
unsigned long |
long |
4 |
q |
long long |
long |
8 |
Q |
unsigned long long |
long |
8 |
f |
float |
float |
4 |
d |
double |
float |
8 |
s |
char[] |
string |
1 |
p |
char[] |
string |
1 |
P |
void * |
long |
4 |
参考文献
- 浅析Python中的struct模块: https://www.cnblogs.com/coser/archive/2011/12/17/2291160.html
- python struct 结构体: https://blog.csdn.net/CLinuxF/article/details/102478001
- Python中对字节流/二进制流的操作:struct模块简易使用教程: https://www.jianshu.com/p/5a985f29fa81
- struct --- 将字节串解读为打包的二进制数据: https://docs.python.org/zh-cn/3/library/struct.html
--------------------- Author: Frytea Title: Python解析变长结构体 Link: https://blog.frytea.com/archives/453/ Copyright: This work by TL-Song is licensed under a Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License.
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- Mybatis学习笔记(五)Mybatis中已经显示数据已修改但数据库中记录未更新问题
- 【自然语言处理(一)】相关基础技能
- MySQL innoDB的事务隔离
- 多元线性回归模型
- (八)golang--复杂类型之指针
- 关于HttpPost 请求和PostMan请求访问出错
- Proxy与Reflect学习笔记
- 确定的有穷状态机(DFA) -- 你来看也能懂的C++代码示例
- python中的any和all函数
- 关于数据库中NOT NUll 的问题。
- 通俗点聊聊算法 -- 链表误成环
- (十)golang--运算符
- (十一)golang--键盘输入
- python中的__call__和__repr__魔术方法
- (十二)golang--进制和位运算