python解析结构体小工具--Apple的学习笔记

一,前言

新的工作内容让我又有了新的创作灵感,今天再创造发明一个小工具,就是用python解析结构体,来进行数据分析。

二,准备工作

所谓准备工作就是在我设计工具的时候,先整理出难点,就是我还不知道的点,然后一个个优先解决。

三,解决问题

1. 结构体解析有库吗?

答:主要就是用python的struct库函数,这个百度一下就知道,主要是pack和unpack。但是这是二进制的格式,不是字符串的,特别是python3.x版本,里面要注意的就是填充匹配的格式。

2. 二进制格式和hex字符串转换怎么便捷处理?

答:用的是binascii库的函数a2b_hex。

四,python小工具代码

我这些小知识点都来自网络中各位的分享,我掌握技术后,做的小工具,也归还网络,供各位参考。保存功能没做,暂时就是简单的能打印出来,支持log和bin文件的解析。

import os
import struct
import binascii


class FaultDataDecode():
    def __init__(self):
        self.InputFileName = []
        self.InputFilePath = os.path.abspath(os.path.join(os.getcwd(),"..")) + "\\input\\"
        self.valueType = 0   # example uint8 xxx, type first
        self.valueName = 1   # example uint8 xxx, name xxx is the second one
        self.strTypes = ''
        self.typeDict ={}

    def getInputFileName(self):
        self.InputFileName = os.listdir(self.InputFilePath)
        print(self.InputFileName)

    def getTypeInfo(self):
        struct_c_path = os.path.abspath(os.path.join(os.getcwd(),"..")) + "\\cfg\\struct_c.txt"
        style = ''
        with open(struct_c_path, 'r') as f:
            for line in f.readlines():
                curLine = line.strip().split()
                #print(curLine)
                if curLine[self.valueType] == 'uint8':
                    style = 'B'
                elif curLine[self.valueType] == 'uint16':
                    style = 'H'
                elif curLine[self.valueType] == 'uint32':
                    style = 'I'
                else:
                    print('type error')
                    exit()  # can't decode,so exit
                self.typeDict[curLine[self.valueName][0:-1]] = style   # the last character is ";", so use [0:-1]
        # print(self.typeDict)
        # print(tuple(self.typeDict.values()))
        # totol 796+1 ,add 60s means one string but the length of string is 60 bytes
        self.strTypes = ''.join(tuple(self.typeDict.values())) + '60s'
        #print(len(self.typeDict))

    def DecodeLogFile(self,filename):
        with open(self.InputFilePath+filename, 'r', encoding='utf8') as fr:
            for line in fr.readlines():
                if line.startswith('['):  # ignore info
                    pass
                else:
                    # delete blank use replace and the last return value so shall use strip()
                    s = line.replace(' ', '').strip()
                    if len(s) == 2000:  # shall fill all data then do the decode
                        #print(s)
                        bytes = binascii.a2b_hex(s)
                        # print(self.bytes)
                        # print('lenOfdata')
                        # print(len(self.bytes))

                        # len of output tuple is 797 means the last one is string, so the valid info is 797-1=796
                        output = struct.unpack(">" + self.strTypes,bytes)
                        # print(len(output) - 1)

                        # i = 0
                        # for key in self.typeDict:
                        #     print(key + "=" + str(hex(output[i])))
                        #     i = i + 1

    def DecodeBinFile(self,filename):
        with open(self.InputFilePath+filename, 'rb') as f:
            bytes = f.read()
        # print(bytes)
        # print('lenOfdata')
        # print(len(bytes))
        # len of output tuple is 797 means the last one is string, so the valid info is 797-1=796
        output = struct.unpack(">" + self.strTypes,bytes)
        # print(len(output) - 1)

        # i = 0
        # for key in self.typeDict:
        #     print(key + "=" + str(hex(output[i])))
        #     i = i + 1

    def DecodeWithInputFile(self):
        self.getInputFileName()
        if(len(self.InputFileName)>0):
            self.getTypeInfo()
        else:
            return  # if no inputfile,stop decode

        for file in self.InputFileName:
            if file.endswith(".log"):
                self.DecodeLogFile(file)
            elif file.endswith(".bin"):
                self.DecodeBinFile(file)
            else:
                return # no valid Input file


if __name__ == "__main__":
    FD = FaultDataDecode()
    FD.DecodeWithInputFile()

你可能感兴趣的:(python解析结构体小工具--Apple的学习笔记)