将ASN.1模式解析为Python代码,并使用每个编码器对其进行编码/解码

asn1PERser的Python项目详细描述


asn1perser

这个库可以将ASN.1文本模式解析为Python代码。每个(对齐的)解码器/编码器包含一个ASN.1,用于解析的模式。

支持的ASN.1类型及其约束是:

ASN.1 TypeSingle valueValue rangeValue sizecan be extended (...)used Python contraint class
INTEGERXXXValueRange
BOOLEAN
ENUMERATEDXExtensionMarker
BIT STRINGXXXValueSize
OCTET STRINGXXXValueSize
CHOICEXExtensionMarker
SEQUENCEXExtensionMarker
SEQUENCE OFXXXSequenceOfValueSize

关于如何使用它们,请看下面的例子。

示例

遵循ASN.1模式:

asn_schema='''\SimpleProtocol DEFINITIONS AUTOMATIC TAGS ::=BEGINSimpleMessage ::= CHOICE {    start    Start,    stop     Stop,    alive    Alive,    data     Data,    ...}Start ::= SEQUENCE {    sequenceNumber    SequenceNumber,    timestamp         UTC-Timestamp,    srcPort           Port,    dstPort           Port}Stop ::= SEQUENCE {    sequenceNumber    SequenceNumber,    timestamp         UTC-Timestamp,    srcPort           Port,    dstPort           Port}Alive ::= SEQUENCE {    timestamp         UTC-Timestamp,    ...}Data ::= SEQUENCE {    sequenceNumber    SequenceNumber,    swRelease         ENUMERATED {rel1, rel2, rel3, ...},    macroId           BIT STRING (SIZE(20)) OPTIONAL,    payload           Payload}Port ::= INTEGER (10000..65535)SequenceNumber ::= INTEGER (0..65535)UTC-Timestamp ::= SEQUENCE {    seconds     INTEGER (0..4294967295),    useconds    INTEGER (0..4294967295)}Payload ::= SEQUENCE (SIZE(1..5)) OF MessageMessage ::= OCTET STRING (SIZE(1..4))END'''

可以解析成如下的python代码:

fromasn1PERserimportparse_asn1_schemaparse_asn1_schema(asn1_schema=asn_schema,output_folder=r'C:/my_code/')

以上代码将在文件夹中创建文件“SimeEffice,Py”(它必须存在)c:/MyOxCult/`:

frompyasn1.type.namedtypeimportNamedType,NamedTypes,OptionalNamedType,DefaultedNamedTypefrompyasn1.type.namedvalimportNamedValuesfromasn1PERser.classes.data.builtinimport*fromasn1PERser.classes.types.typeimportAdditiveNamedTypesfromasn1PERser.classes.types.constraintimportMIN,MAX,NoConstraint,ExtensionMarker,SequenceOfValueSize, \
    ValueRange,SingleValue,ValueSize,ConstraintOr,ConstraintAndclassPort(IntegerType):subtypeSpec=ValueRange(10000,65535)classSequenceNumber(IntegerType):subtypeSpec=ValueRange(0,65535)classMessage(OctetStringType):subtypeSpec=ValueSize(1,4)classUTC_Timestamp(SequenceType):classseconds(IntegerType):subtypeSpec=ValueRange(0,4294967295)classuseconds(IntegerType):subtypeSpec=ValueRange(0,4294967295)rootComponent=AdditiveNamedTypes(NamedType('seconds',seconds()),NamedType('useconds',useconds()),)componentType=rootComponentclassStart(SequenceType):rootComponent=AdditiveNamedTypes(NamedType('sequenceNumber',SequenceNumber()),NamedType('timestamp',UTC_Timestamp()),NamedType('srcPort',Port()),NamedType('dstPort',Port()),)componentType=rootComponentclassStop(SequenceType):rootComponent=AdditiveNamedTypes(NamedType('sequenceNumber',SequenceNumber()),NamedType('timestamp',UTC_Timestamp()),NamedType('srcPort',Port()),NamedType('dstPort',Port()),)componentType=rootComponentclassAlive(SequenceType):subtypeSpec=ExtensionMarker(True)rootComponent=AdditiveNamedTypes(NamedType('timestamp',UTC_Timestamp()),)componentType=rootComponentclassPayload(SequenceOfType):subtypeSpec=SequenceOfValueSize(1,5)componentType=Message()classData(SequenceType):classswRelease(EnumeratedType):subtypeSpec=ExtensionMarker(True)enumerationRoot=NamedValues(('rel1',0),('rel2',1),('rel3',2),)namedValues=enumerationRootclassmacroId(BitStringType):subtypeSpec=ValueSize(20,20)rootComponent=AdditiveNamedTypes(NamedType('sequenceNumber',SequenceNumber()),NamedType('swRelease',swRelease()),OptionalNamedType('macroId',macroId()),NamedType('payload',Payload()),)componentType=rootComponentclassSimpleMessage(ChoiceType):subtypeSpec=ExtensionMarker(True)rootComponent=AdditiveNamedTypes(NamedType('start',Start()),NamedType('stop',Stop()),NamedType('alive',Alive()),NamedType('data',Data()),)componentType=rootComponent

当模式被解析时,它可以被使用-消息可以被创建、编码和解码,使用每个编码器/解码器,以字节为单位 或python结构:

fromasn1PERserimportencode,decodefromSimpleProtocolimport*'''simple_message SimpleMessage ::= alive : {    timestamp {        seconds 1557528149,        useconds 12345    }}'''utc_timestamp=UTC_Timestamp()utc_timestamp['seconds']=UTC_Timestamp.seconds(1557528149)utc_timestamp['useconds']=UTC_Timestamp.useconds(12345)msg_alive=Alive()msg_alive['timestamp']=utc_timestampsimple_message=SimpleMessage()simple_message['alive']=msg_aliveper_bytes=encode(asn1Spec=simple_message)print('encoded alive bytes as hex string:')print(per_bytes.hex())print('\n')decoded=decode(per_stream=per_bytes,asn1Spec=SimpleMessage())print('decoded alive message structure as string...:')print(decoded)print('...can be accessed like dictionary:')print(decoded['alive']['timestamp']['seconds'])

以上将输出:

encoded alive bytes as hex string:
4c5cd5fe55403039


alive message structure as string...:
SimpleMessage:
 alive=Alive:
  timestamp=UTC_Timestamp:
   seconds=1557528149
   useconds=12345



...can be accessed like dictionary:
1557528149

下一条消息:

'''simple_message SimpleMessage ::= start : {    sequenceNumber    10,    timestamp {        seconds 1557528149,        useconds 12345    },    srcPort    65533,    dstPort    10000}'''utc_timestamp=UTC_Timestamp()utc_timestamp['seconds']=UTC_Timestamp.seconds(1557528149)utc_timestamp['useconds']=UTC_Timestamp.useconds(12345)msg_start=Start()msg_start['sequenceNumber']=SequenceNumber(10)msg_start['timestamp']=utc_timestampmsg_start['srcPort']=Port(65533)msg_start['dstPort']=Port(10000)simple_message=SimpleMessage()simple_message['start']=msg_startper_bytes=encode(asn1Spec=simple_message)print('encoded start bytes as hex string:')print(per_bytes.hex())print('\n')decoded=decode(per_stream=per_bytes,asn1Spec=SimpleMessage())print('start message structure as string...:')print(decoded)print('...can be accessed like dictionary:')print(decoded['start']['srcPort'])

以上将输出:

encoded start bytes as hex string:
00000ac05cd5fe55403039d8ed0000


start message structure as string...:
SimpleMessage:
 start=Start:
  sequenceNumber=10
  timestamp=UTC_Timestamp:
   seconds=1557528149
   useconds=12345

  srcPort=65533
  dstPort=10000


...can be accessed like dictionary:
65533

下一条消息:

'''simple_message SimpleMessage ::= data : {    sequenceNumber    55555,    swRelease  rel2,    macroId    '11110000111100001111'B,    payload {        'DEAD'H,        'BEEF'H,        'FEED'H,        'AA'H,        'BBBBBBBB'H    }}'''data_payload=Payload()data_payload.extend([Message(hexValue='DEAD')])data_payload.extend([Message(hexValue='BEEF')])data_payload.extend([Message(hexValue='FEED')])data_payload.extend([Message(hexValue='AA')])data_payload.extend([Message(hexValue='BBBBBBBB')])msg_data=Data()msg_data['sequenceNumber']=SequenceNumber(55555)msg_data['swRelease']=Data.swRelease('rel2')msg_data['macroId']=Data.macroId(binValue='11110000111100001111')msg_data['payload']=data_payloadsimple_message=SimpleMessage()simple_message['data']=msg_dataper_bytes=encode(asn1Spec=simple_message)print('encoded data bytes as hex string:')print(per_bytes.hex())print('\n')decoded=decode(per_stream=per_bytes,asn1Spec=SimpleMessage())print('data message structure as string...:')print(decoded)print('...can be accessed like dictionary:')print(bytes(decoded['data']['payload'][0]).hex())

以上将输出:

encoded data bytes as hex string:
70d90320f0f0f880dead40beef40feed00aac0bbbbbbbb


data message structure as string...:
SimpleMessage:
 data=Data:
  sequenceNumber=55555
  swRelease=rel2
  macroId=986895
  payload=Payload:
   0xdead   0xbeef   0xfeed   0xaa   0xbbbbbbbb


...can be accessed like dictionary:
dead

下一条消息:

'''simple_message SimpleMessage ::= data : {    sequenceNumber    256,    swRelease  rel3,    payload {        'DEADBEEF'H    }}'''data_payload=Payload()data_payload.extend([Message(hexValue='DEADBEEF')])msg_data=Data()msg_data['sequenceNumber']=SequenceNumber(256)msg_data['swRelease']=Data.swRelease('rel3')msg_data['payload']=data_payloadsimple_message=SimpleMessage()simple_message['data']=msg_dataper_bytes=encode(asn1Spec=simple_message)print('encoded data bytes as hex string:')print(per_bytes.hex())print('\n')decoded=decode(per_stream=per_bytes,asn1Spec=SimpleMessage())print('data message structure as string...:')print(decoded)print('...can be accessed like dictionary:')print(decoded['data']['swRelease'])

以上将输出:

encoded data bytes as hex string:
60010043deadbeef


data message structure as string...:
SimpleMessage:
 data=Data:
  sequenceNumber=256
  swRelease=rel3
  payload=Payload:
   0xdeadbeef


...can be accessed like dictionary:
rel3

其他信息

有关更多示例,请参见库测试:

  • 分析测试,位于test/parsing/folder中。
  • 编码/编码测试,位于测试/每个文件夹中。

所有上述示例和测试,使用: https://asn1.io/asn1playground/

这个库广泛地继承了pyasn1库,因此ber和其他编码也应该在这里工作。

解析可能需要时间-当试图解析大约2000行asn.1时,需要15-20分钟。 解析测试也需要时间。

欢迎加入QQ群-->: 979659372 Python中文网_新手群

推荐PyPI第三方库


热门话题
验证Java验证用户输入的一系列数字   java如何在SpringBoot中字段验证失败时在ConstraintViolationException中获取RequestParam名称   java如何解决Vertx阻塞DNS问题   java意外类型平均值   java如何将dataframe的UUID列转换为包含相同十六进制序列的简单字符串?   身份散列映射的java用法   java无法在eclipse中导入现有项目   进程从运行的java程序中获取CPU号   java将文本视图的特定行滚动到顶部在最后一个屏幕上不起作用   无法初始化java SpringSecurityFilterChain   java当我在项目中使用volatile时,为什么下面的代码显示不同的结果?   是否有转换java的标准方法。util。函数,消费者<T>转换为java。util。作用函数<T,Void>   java nginx分块传输编码失败   java如何将几个IF转换为一个循环   java URI从路径中删除/删除