python工具-c-struct-decode
示例
# 编译运行C代码
gcc c-struct.c
./a.out
# 生成 1.bin 文件, 内容是一个 demo_head+3*demo_info
# 使用 python 解析
python c-struct-decode.py
# 输入结果如下:
1.txt
unpack requires a buffer of 4 bytes
type:1
version:0
path:12
indexs:4
===========index: 0==============
timestamp:1886221359
flag:0
desc:
===========index: 1==============
timestamp:256
flag:0
desc:hello
===========index: 2==============
timestamp:558
flag:0
desc:hello
===========index: 3==============
timestamp:814
flag:0
desc:hello
C 代码写入
#include <stdio.h>
#include <stdint.h>
#pragma pack(4) // 4字节对齐
typedef struct _head_ {
uint32_t type;
uint64_t version;
char path[12];
}demo_head;
#pragma pack(1) // 1字节对齐
typedef struct _info_ {
uint32_t timestamp;
char flag;
char desc[6];
}demo_info;
#pragma pack()
int main(){
FILE* f = fopen("1.bin", "wb");
if (f == NULL) {
printf("fopen file fail.\n");
return -1;
}
demo_head h = {1,0,"/tmp"};
fwrite(&h, sizeof(demo_head), 1, f);
for (size_t i = 0; i < 3; i++) {
demo_info info = {i+1, 1, "hello."};
fwrite(&info, sizeof(demo_info), 1, f);
}
fclose(f);
return 0;
}
python 代码读取
import argparse
import struct
import os
def get_unpack_info(f, size):
if size == 4:
return struct.unpack("I", f.read(size))[0]
elif size == 1:
return struct.unpack("B", f.read(size))[0]
elif size == 8:
return struct.unpack("Q", f.read(size))[0]
class demo_info:
sizes = [4,1,6]
def __init__(self) -> None:
self.timestamp = 0 # 4
self.flag = 0 # 1
self.desc = 0 # 6
def __str__(self) -> str:
ret = "timestamp:" + str(self.timestamp) + "\n"
ret += "flag:" + str(self.flag) + "\n"
ret += "desc:" + str(self.desc) + "\n"
return ret
class demo_head:
sizes = [4,8,12]
def __init__(self) -> None:
self.type = 0 # 4
self.version = 0 # 8
self.path = "" # 12
self.indexs = []
def __str__(self) -> str:
ret = "type:" + str(self.type) + "\n"
ret += "version:" + str(self.version) + "\n"
ret += "path:" + str(self.path) + "\n"
ret += "indexs:" + str(len(self.indexs)) + "\n"
return ret
def read_demo_data(file_name):
head = demo_head()
with open(file_name, "rb") as f:
head.type = get_unpack_info(f, demo_head.sizes[0])
head.version = get_unpack_info(f, demo_head.sizes[1])
head.path = demo_head.sizes[2]
while(True):
index = demo_info()
try:
index.timestamp = get_unpack_info(f, demo_info.sizes[0])
index.flag = get_unpack_info(f, demo_info.sizes[1])
index.desc = str(f.read(demo_info.sizes[2]).decode("utf-8"))
head.indexs.append(index)
except Exception as e:
print(e)
break
return head
if __name__ == "__main__":
parser = argparse.ArgumentParser()
parser.add_argument('--path', type=str, default = "1.bin")
args = parser.parse_args()
print(args.path)
head = read_demo_data(args.path)
if head:
print(head)
for i, index in enumerate(head.indexs):
print(f"===========index: {i}==============")
print(index)