听起来你需要了解ASN.1标记的介绍。从两个角度来看待这个问题。X.690定义了BER/CER/DER编码规则,因此它回答了如何编码标记的问题。X.680定义了ASN.1本身,因此它定义了标记的语法和规则。这两个规范都可以在ITU-T网站上找到。我会给你一个快速概述。
标记在BER/DER/CER中用于标识类型。它们特别适用于区分SEQUENCE的组件和CHOICE的替代项。
标记结合了标记类和标记号。标记类包括UNIVERSAL、APPLICATION、PRIVATE和CONTEXT-SPECIFIC。UNIVERSAL类基本上用于内置类型。APPLICATION通常用于用户定义的类型。CONTEXT-SPECIFIC通常用于构造类型(SEQUENCE、CHOICE、SEQUENCE OF)中的组件。从语法上讲,在ASN.1模块中指定标记时,它们写在方括号内:[tag_class tag_number];对于CONTEXT-SPECIFIC,tag_class被省略。因此,[APPLICATION 10]或[0]。
虽然每种ASN.1类型都有一个相关联的标签,但从语法上讲,还有“标记类型(TaggedType)”,它由ASN.1作者用于指定要对类型进行编码的标签。基本上,标记类型将一个标签前缀放在一个类型前面。例如:
MyType ::= SEQUENCE {
field_with_tagged_type [0] UTF8String
}
在TaggedType中的标签可以是显式的或隐式的。如果是显式的,这意味着我希望原始标签被明确编码。如果是隐式的,这意味着我只想让我指定的标签被编码。在显式情况下,BER编码会产生一个嵌套的TLV(标签-长度-值):外部标签(如上例中的[0]),长度,然后是另一个TLV作为值。在该示例中,这个内部TLV将具有UTF8String的[UNIVERSAL 12]标签。
标签是显式还是隐式取决于您如何编写标签以及标记环境。例如:
MyType2 ::= SEQUENCE {
field_with_explicit_tag [0] EXPLICIT UTF8String OPTIONAL,
field_with_implicit_tag [1] IMPLICIT UTF8String OPTIONAL,
field_with_tag [2] UTF8String OPTIONAL
}
如果未指定IMPLICIT或EXPLICIT,则有一些规则定义标记是显式还是隐式(请参见X.680 31)。这些规则考虑了为ASN.1模块定义的标记环境。ASN.1模块可以将标记环境指定为IMPLICIT TAGS、EXPLICIT TAGS或AUTOMATIC TAGS。
粗略地说,如果未为标记指定IMPLICIT或EXPLICIT,则在标记环境为EXPLICIT时,标记将为显式,在标记环境为IMPLICIT或AUTOMATIC时,标记将为隐式。自动标记环境基本上与IMPLICIT标记环境相同,只是为SEQUENCE和CHOICE类型的成员自动分配唯一标记。
请注意,在上面的示例中,MyType2的三个组件都是可选的。在BER/CER/DER中,解码器将根据编码的标记知道哪个组件存在(这显然最好是唯一的)。