问题描述
我正在尝试使用asn1tools
Python库对符合Ember+标准的BER消息进行解码和编码。
That standard’s DTD在某些地方使用ASN.1的RELATIVE-OID
类型。但是,asn1tools
对此类型一无所知,可能是因为底层的pyasn1
库没有实现它(目前还没有a pull request)。这就是为什么我无法在Python程序中使用该DTD的原因。但是我真的必须。
我所看到的,我的选择是创建包含pyasn1
公关的RELATIVE-OID
的修补版本,并使asn1tools
与之一起工作,或者以某种方式建立解决方法在DTD中。
我已经尝试过将RELATIVE-OID ::= [UNIVERSAL 13] OCTET STRING
添加到DTD,但是现在asn1tools
的回答是Expected RELATIVE-OID with tag '2d' at offset 10,but got '0d'.
,基本上它似乎接受了我的定义,但是使它“通用构造为13”消息将其标记为“通用原始 13”。
这是我的限制条件:
- 我基本上已经使用
asn1tools
,我的代码已经严重依赖于它。 - 我具有能够解析和创建与将这些字段标记为
0d
的其他第三方客户端兼容的消息。 - 我可以在DTD中随意编辑,例如添加定义
RELATIVE-OID
的类型(但以哪种方式?)或替换每次出现的RELATIVE-OID
与其他内容配合使用,只要它仍能与将字段标记为0d
的消息一起使用。 - 我完全可以将
RELATIVE-OID
的值作为bytes
或类似内容的不透明斑点,这就是为什么我首先尝试解决OCTET STRING
的原因。 / li>
我的ASN.1知识有限,而且我不擅长编写DTD。也许有一种方法可以将类型强制为“原始”类型?我很高兴提出任何建议。如果您想自己尝试一下,请使用上面的DTD链接。然后,使用以下Python代码:
import asn1tools
spec = asn1tools.compile_files('GlowDtd.asn1')
print(spec.decode('Root',b'`\x80k\x80\xa0\x80b\x80\xa0\x03\x02\x01 \xa1\x03\x02\x01\xff\x00\x00\x00\x00\x00\x00\x00\x00'))
# should result in ('elements',[('element',('command',{'number': 32,'options': ('dirFieldMask',-1)}))])
print(spec.decode('Root',b'`\x80k\x80\xa0\x80j\x80\xa0\x03\r\x01\x01\xa2\x80d\x80\xa0\x80b\x80\xa0\x03\x02\x01 \xa1\x03\x02\x01\xff\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'))
# doesn't work because it uses RELATIVE-OID
解决方法
尝试
RELATIVE-OID ::= [UNIVERSAL 13] IMPLICIT OCTET STRING