【问题标题】:How to ASN.1 encode a map / dictionary?如何 ASN.1 编码地图/字典?
【发布时间】:2017-12-18 16:50:04
【问题描述】:

我的 ASN.1 库[1][2],在 Java 和 Squeak/Pharo 中,支持序列、sequence-of 和 mapped-sequence,以及 set、set-of 和 mapped-set。我希望映射的缺失集合类型是字典或映射。

是否有任何标准方法可以将键/值对字典映射到稳健的 ASN.1 编码?是否有指向此通用标准的链接和/或映射键/值对的映射/字典的示例?也许可以指出一个未被发现的 SO 讨论。

我相信我想要 ANY 类型的键/值表示,而不是使用 MappedSequence。问题是自我描述的,MappedSequence 有一组预定义的结构元素,因此排序很重要,因为键是隐式使用的。我想要更多的自描述 ANY 类型,其中包括无序的键/值对。这有道理吗? ;)

我正在尝试创建一个通用对象映射,一种 ANY 类型,但它需要所述通用对象的实例变量的键/值对。我希望使用语言反射,基于与语言类匹配的编码类名,然后生成具有相同结构的 ASN.1“ANY”类型,然后使用该类型来解码编码对象。在任何一种语言实现中,我都没有实现健壮的 ANY 类型。

谢谢。

[1] - https://github.com/CallistoHouseLtd/ASN1

[2] - http://www.squeaksource.com/Cryptography/Cryptography-HenryHouse.113.mcz

【问题讨论】:

    标签: java smalltalk pharo asn.1 squeak


    【解决方案1】:

    SNMP 使用 ASN.1 编码和键值对,因此这可能是一个很好的起点。 RFC 3416 将语法定义为名为 SNMPv2-PDU 的 ASN.1 模块。

    VarBind 是键值对:

    VarBind ::= SEQUENCE {
            name ObjectName,
    
            CHOICE {
                value          ObjectSyntax,
                unSpecified    NULL,    -- in retrieval requests 
    
                                        -- exceptions in responses
                noSuchObject   [0] IMPLICIT NULL,
                noSuchInstance [1] IMPLICIT NULL,
                endOfMibView   [2] IMPLICIT NULL
            }
        }
    

    ObjectName 为键:

    ObjectName ::= OBJECT IDENTIFIER
    

    ObjectSyntax 作为值:

    ObjectSyntax ::= CHOICE {
          simple           SimpleSyntax,
          application-wide ApplicationSyntax }
    
    SimpleSyntax ::= CHOICE {
          integer-value   INTEGER (-2147483648..2147483647),
          string-value    OCTET STRING (SIZE (0..65535)),
          objectID-value  OBJECT IDENTIFIER }
    
    ApplicationSyntax ::= CHOICE {
          ipAddress-value        IpAddress,
          counter-value          Counter32,
          timeticks-value        TimeTicks,
          arbitrary-value        Opaque,
          big-counter-value      Counter64,
          unsigned-integer-value Unsigned32 }
    

    一个键值对序列是VarBindList:

    VarBindList ::= SEQUENCE (SIZE (0..max-bindings)) OF VarBind
    

    SNMP 数据包中的VarBindList 示例 (BER-encoded):

    30|36                                  [SEQUENCE]
     30|10                                  [SEQUENCE]
      06|0a|2b 06 01 02 01 02 02 01 04 01    [OID] 1.3.6.1.2.1.2.2.1.4.1
      02|02|05 dc                            [INTEGER] 1500
     30|12                                  [SEQUENCE]
      06|0a|2b 06 01 02 01 02 02 01 05 01    [OID] 1.3.6.1.2.1.2.2.1.5.1
      42|04|05 f5 e1 00                      [Gauge32] 100000000
     30|14                                  [SEQUENCE]
      06|0a|2b 06 01 02 01 02 02 01 06 01    [OID] 1.3.6.1.2.1.2.2.1.6.1
      04|06|53 74 72 69 6e 67                [OCTET STRING] "String"
    

    【讨论】:

    • 我不知道 SNMP 的详细信息,虽然我过去处理过 MIB - 感谢您的启发。这激发了我可以使用 InstanceVariableStructure 键/值 {Utf8String, ANY} 序列的序列来定义 ObjectStructure 的想法。然后,关于以下答案,在我的根消息发送结构(其中 5 个中的 2 个)中使用 ANY 来保存已编码的参数对象图。在运行时使用 ObjectStructure 类型来解码找到的任何 ANY。 ObjectStructure ::= SEQUENCE {
    【解决方案2】:

    AFAIK,在内置 ASN.1 类型中有一个直接等效的 Mapping 数据结构。

    您可以使用SET OF 容器类型来保存表示键值对的二元素SEQUENCE 类型吗?但是,这不会自动使您免于重复。您必须确保代码中键的唯一性。或者,您可能需要查看 ASN.1 约束,以防您可以使用它们来描述元素的唯一性。

    ANY 类型通常用于将类型定义推迟到运行时。这样接收端就可以查看其他地方(参见ANY DEFINED BY)并找出ANY 字段中的内容。然后它可以根据刚刚获得的正在处理的字段结构的知识对其内容进行解码。当您在协议设计时无法知道所有可能的数据类型时,这非常有用(例如,它是可扩展性功能)。

    【讨论】:

    • 我明白你关于重复的观点,但这符合我的观点,即编码不应该指定约束,我可以让系统在结构定义外部强制执行。我意识到这意味着规范之外的额外规则,但是在 OO 出现几十年后,我们无法在 ASN.1 中表达任意对象。我非常喜欢 ASN.1,但是有一些弱点,留给使用这种编码的封装程序。我的感觉。这是 ANY 的工作原理吗?封装程序在运行时指定。作为我发布的答案,ANY 将是一个 ObjectStructure。
    • 这里的问题是 ANY 是 1994 年撤销的 1988 ASN.1 的一部分。如果您使用 1994 年或更高版本的任何 ASN.1 版本而不是过时的 1988 版本,您会正在使用开放类型(ANY 的替代品),它允许您显式定义对象表,您可以通过该表来约束开放类型。
    • @PaulThorpe 是不是 ASN.1 INFORMATION OBJECT CLASS 以向后兼容的方式弃用了 ANY
    • @ZZimbarra 请注意,使用ANY 并不意味着背离ASN.1 结构定义。您可能在 ASN.1 中定义了所有结构,但是使用 ANY 您不是静态嵌套结构(例如在 ASN.1 规范设计时),而是让您的解码器从一个字段的潜在候选者的开放式集合,并在运行时将其插入。
    • @IlyaEtingof Modern ASN.1 用开放类型替换 ANY(以向后兼容的方式),开放类型可以以 ASN.1 编译器完全理解的方式进行约束。 1994 年从 ASN.1 中删除的 ANY DEFINED BY 没有任何方法可以根据 ANY DEFINED BY 引用的组件来定义查找表。信息对象集提供该功能,同时保持与 ANY 和 ANY DEFINED BY 的向后兼容性。 1988 年版本的 ASN.1 于 1994 年被 ITU-T 和 ISO 撤回(未弃用)。
    【解决方案3】:

    可能是这样的…… `

    DeliverMessage ::= SEQUENCE {
        receiverID               INTEGER,
        selector                 UTF8STRING,
        arguments                SEQUENCE-OF ObjectStructure,
        answerID                 INTEGER,
        redirector               ObjectStructure }
    
    ObjectStructure ::= SEQUENCE {
        className                UTF8STRING,
        instanceVariables        SEQUENCE-OF InstanceVariable }
    
    InstanceVariable ::= SEQUENCE {
        instanceVariableName     UTF8STRING,
        value                    ANY }
    

    `

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-12-27
      • 2011-04-07
      • 2022-01-22
      • 2012-04-11
      • 1970-01-01
      • 2015-04-30
      • 2018-03-20
      • 1970-01-01
      相关资源
      最近更新 更多