一,前言
新的工作内容让我又有了新的创作灵感,今天再创造发明一个小工具,就是用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()