ASN.1表达SEQUENCE大小约束

时间:2016-06-21 00:06:37

标签: asn.1

我想在ASN.1中描述现有的数据结构,因此我可以使用合适的库来解码/编码/验证事务,而无需从头开始编写所有内容。

此外:

  • 我无法更改任何数据结构;
  • 所有字段都是ASCII字符;
  • 在大多数数组(SEQUENCES)的定义中,发送的元素数由前面的计数器字段定义。

考虑以下简化示例:

World-Schema DEFINITIONS AUTOMATIC TAGS ::= 
BEGIN
  Test ::= SEQUENCE {
     id IA5String (SIZE(5)),
     nbData IA5String (SIZE(2)),
     dataList ListOfData
  }
  ListOfData ::= SEQUENCE(SIZE(0..99)) OF DataPoint
  DataPoint ::= SEQUENCE {
     x IA5String (SIZE(2)),
     y IA5String (SIZE(2))
  }
END

字段nbData指示传输数据流中存在的dataPoint个元素的数量。

除了nbData实际上是一个编码为字符串的整数之外,这必须是压缩传输数据的一种非常常见的方式。尽管如此,我仍然试图找到一种方法来定义这种结构。

如何在ASN.1中表达此约束?

3 个答案:

答案 0 :(得分:1)

这种约束不是ASN.1的“本机”,特别是因为包含整数的字段表示为字符串。虽然ECN(编码控制符号)可以处理这个问题,但最好使用ASN.1调用的“用户定义约束”,例如:

Test ::= SEQUENCE {
     id IA5String (SIZE(5)),
     nbData IA5String (SIZE(2)),
     dataList ListOfData
} (CONSTRAINED BY {-- English text describing your constraint --})

某些商业ASN.1编译器能够使用此约束表示法在生成的编码器/解码器中生成函数存根,以允许您强制执行超出ASN.1约束表示法的内置功能的约束。

使用SEQUENCE上的“WITH COMPONENTS”约束可以使用更复杂的方法强制执行约束,但是为完成此操作而写入完整约束所需的文本量不太可能值得。

答案 1 :(得分:0)

你如何在ASN.1中表达这种约束?你不能。

您可以查看ECN,它是一种(相当复杂的)语法,是ASN.1系列的一部分,与ASN.1一起使用以指定非标准(即除了BER之外) PER等编码。

我不知道ECN是否足以表达您想要的编码,但我认为很可能。但是,您必须将ECN计算出来,然后您必须找到支持ECN的工具。祝你好运!

答案 2 :(得分:0)

您正在将ASN.1模式(该消息定义了消息的结构和允许的值)与符合该模式的特定消息的内容相混淆。编写架构时,可以为所有消息定义允许的数据点数(0..99)。

在发送消息时,可以在运行时定义特定消息中的DataPoints数量。诸如BER或XER之类的编码规则指定了消息的传输方式-您向编码器提供具有17个DataPoints的ListOfData消息,它将:

1) check that the number of points is within the range allowed by the schema (0..99), and
2) send that list of 17 DataPoints as specified by the encoding rules.

当您收到消息时,ListOfData将具有从编码规则中得知的大小(17),并且该大小将再次针对架构进行验证(0..99)。

如果要在程序中创建单独的nbData变量,可以在解码消息后 将ListOfData的长度复制到其中。但是nbData不是在架构内指定并在消息内冗余传输的变量。

如果您无法更改诸如Test数据结构之类的内容来完全摆脱nbData,则只需在发送方使用正确的值填充它即可。在接收方,可以将其忽略,或者在对消息进行解码后将其与正确的值进行比较。不要理会ASN.1来添加约束。弄乱它的正确方法是删除碎片。


ASN.1的优点是它是一种抽象数据描述语言,与编程语言和序列化格式无关。如果使用像C这样的低级语言进行编程,则将使用具有整数个数据点(nbData)和指向struct DataPoint的指针的内存结构。但是,如果您使用的是Java,JS,Python等高级语言,则ListOfData将是数组或列表,并且将具有长度。

因此,如果您使用C进行编程,则您的ASN.1序列化库可能会为您提供一个ListOfData结构,其中内置了类似nbData的结构。但是,如果您使用Python进行编程,该库将为您提供一个列表,并且如果您想要类似nbData的内容,则可以使用len(ListOfData)获得它。

ASN.1消除了实现上的差异,这就是为什么nbData不是独立的ASN.1变量,而是内置于ListOfData中的原因。