将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将json反序列化为列表<Object>   Spring框架中的java回滚机制   java如何使反射在JDK 16及更高版本上工作?   java终结器如何导致可移植性问题?   java Hibernate使用ON子句或alternative左连接获取   java aws codebuild maven项目失败“保存的引用不明确”   并发Java多线程读取单个大文件   java如果输入仅由1和0组成,请将其从二进制转换为十进制   java在RealmRecyServiceAdapter上调用updateData实际上并没有更新数据   javajsf:h commandlink操作是打开同一页面的新弹出窗口,而不是调用bean方法   java我们可以为其中一个变量同时添加@Column和@OneToOne注释吗?   java JBoss AS 7自定义登录模块从未调用   如何检查Java中是否存在数组中的元素   java Spring重试:未调用带@Recover注释的方法   如何解析带有Java错误HTTP格式问题的php消息   java如何在weblogic中部署可选的包共享库   java将配置单元中的数据集保存为avro格式的合并列   用Guice注入java泛型   java单选按钮组和额外选项   javajackson:如何读取字符串作为列表?