python工具-c-struct-decode

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 
#include 

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

你可能感兴趣的:(工具类,python,c语言,开发语言)