通过树和递归构造字典

ASN编码中会出现形如结构体嵌套的数据结构,例如某ASN文件结构为:
–=================================================
– OperationID: BigDataDriving (0x0001)
–=================================================
OpBigDataSrvSrvFor
Driving-NotificationCyclic ::= SEQUENCE {
prkgEmgyBrkSysSts PrkgEmgyBrkSysSts OPTIONAL,
vehSpdLgt VehSpdLgt OPTIONAL,
……
}
……
PrkgEmgyBrkSysSts ::= ENUMERATED{
pEBSysSts-Off (0),
pEBSysSts-Standby (1),
……
}
……
VehSpdLgt ::= SEQUENCE{
vehSpdLgtA INTEGER(0…31970),
……
}
其中OpBigDataSrvSrvForSmartDriving-NotificationCyclic是一个Operation,类似一个结构体,结构体成员有可能是基本数据类型,如PrkgEmgyBrkSysSts 为枚举型,也有可能是嵌套了另一个结构体,如VehSpdLgt 。
ASN的注释是以“–”开头的,需要忽略。
当需要对ASN Operation进行编码时需要对Operation(可以理解为结构体)的所有成员进行赋值,并以字典形式作为编码的输入。字典格式为:
dictType = {“prkgEmgyBrkSysSts ”:enumValue, “VehSpdLgt”:{“vehSpdLgtA ”:intValue , …}, …}
从ASN文件输入到打印出字典,需要python对文本进行处理,Python源代码如下:
BaseFunc.py:

import re
import random

def getRandEnum(lineList, LineIndex):
    lineStr = ""
    EnumStrList = []
    while('}' not in lineStr):
        LineIndex = LineIndex + 1
        lineStr = lineList[LineIndex]
        EnumStr = ((lineStr.strip()).split(' '))[0]
        EnumStrList.append(EnumStr)
    EnumStrList.pop()
    return random.choice(EnumStrList)

# # uinit test start
# lineList = [\
# "--=================================================",\
# "MemPosnFromTelm ::= ENUMERATED {",\
# "memPosn-ProfPosn (0),",\
# "memPosn-MemBnk1 (1),",\
# "memPosn-MemBnk2 (2),",\
# "memPosn-MemBnk3 (3)",\
# "}",\
# "--================================================="]
# print("---------------test Func getRandEnum----------------")
# print(getRandEnum(lineList, 1))
# # uinit test end
def isEnumTypeAndGetEnumValue(keyTypeStr, inputFileClass):
    for i in range(0, inputFileClass.lineNum - 2):
        line = inputFileClass.lineList[i]
        if (re.search(keyTypeStr + '\s*::= ENUMERATED', line)):
            randEnum = getRandEnum(inputFileClass.lineList, i)
            return True, randEnum
    return False, "Dumy"

# # uinit test start
# print("-----------test Func isEnumTypeAndGetEnumValue-------------")
# isEnumTypeAndGetEnumValue("ProfPenGidSts", inputFileObj)
# # uinit test end

def isBaseTypeAndReturnValue(keyTypeStr, inputFileObj):
    if ("INTEGER" in keyTypeStr):
        result = re.split(r'[\.\(\)]', keyTypeStr, 10)
        while '' in result:
            result.remove('')
        low = int(result[1])
        up = int(result[2])
        value = random.randint(low,up)
        #print (value)
        return True, value
    elif ("BOOLEAN" in keyTypeStr):
        listBoolean = ["True", "False"]
        value = random.choice(listBoolean)
        #print (value)
        return True, value
    elif ("PrintableString(SIZE(16))" in keyTypeStr):
        return True, "1234567890ABCDEF"
    isEnumType, randEnumValue = isEnumTypeAndGetEnumValue(keyTypeStr, inputFileObj)
    if (isEnumType):
        return True, randEnumValue
    else:
        return False, keyTypeStr

BuildDict.py:

import re
import BaseFunc

filePath = "D:/BDU/IPRouting_Test/asn/0xB3_V028.asn"
OpName = "OpPersonalSettingReq-SetRequestNoReturn"

class inputFileClass():
    def __init__(self, filePath, OpName):
        self.filePath = filePath
        self.OpName = OpName
        with open(filePath, 'r') as fileHandle:
            self.lineList = fileHandle.readlines()
            self.lineNum = len(self.lineList)  

inputFileObj = inputFileClass(filePath, OpName)

class TreeNode():
    def __init__(self, value = {}):
        self.SigValue = value
    SigName = ""
    SigType = ""

class OpTree:
    def __init__(self, node):
        self.node = node
        self.children = []
    def addChild(self, child):
        self.children.append(child)
    def getChildren(self):
        return self.children

lineList = inputFileObj.lineList
lineNum  = inputFileObj.lineNum
root_key = "OpBigDataSrvSrvForSmartDriving-NotificationCyclic"
rootNode = TreeNode()
rootNode.SigName = "Dummy"
rootNode.SigType = root_key
rootTree = OpTree(rootNode) # init tree, add root tree Node

def CreatTree(Tree):
    father = Tree
    for i in range(0, lineNum):
        if re.search("^--", lineList[i].strip()): #ignore comments
            continue
        if (re.search(father.node.SigType + '\s*::=\s*SEQUENCE\s*{', lineList[i])):
            startLine = i + 1
            for j in range(startLine, lineNum): # after find startline, find endline immediately
                if ('}' in lineList[j]):
                    endLine = j
                    break
            for k in range(startLine, endLine):
                genNode = TreeNode()
                genNode.SigName = (re.split(',*\s+', ((lineList[k].strip()).strip(','))))[0]
                genNode.SigType = (re.split(',*\s+', ((lineList[k].strip()).strip(','))))[1]
                isBaseType, Value = BaseFunc.isBaseTypeAndReturnValue(genNode.SigType, inputFileObj)
                if (isBaseType):
                    genNode.SigValue = Value
                child = OpTree(genNode)
                father.addChild(child)
                CreatTree(child)
CreatTree(rootTree)

resultDict = {}
def depthFirstByRecursion(tree):
    tempDict = {}
    children = tree.getChildren()
    for child in children:
        name = child.node.SigName
        if (child.children == []):
            value = child.node.SigValue
        else:
            value = depthFirstByRecursion(child)
        tempDict[name] = value  
    return tempDict
resultDict = depthFirstByRecursion(rootTree)
print(resultDict)

右边的写法
右边的写法是错误的children

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值