T ::= [1] IMPLICIT T1 T1 ::= [5] IMPLICIT T2
T2 ::= [APPLICATION 0] IMPLICIT INTEGER 对于类型T,只有Tag值 1被编码。
这种模式需要接收方能保证清楚知道抽象语法,能正确解码。 III. Global Tagging Mode
可以在模块定义时,声明模块全局Tag模式。可以是EXPLICIT TAGS、IMPLICIT TAGS和AUTOMATIC TAGS。
IMPLICIT TAGS:模块内所有SEQUENCE、SET和CHOICE的成员都是IMPLICIT模式(除非它是CHOICE类型、开放类型或者一个参数类型)。但不影响IMPORTS的内容。
AUTOMATIC TAGS:模块内所有SEQUENCE、SET和CHOICE类型ASN.1编译器会自动从0开始,步长为1进行自动编码。而其中的成员则用IMPLICIT模式,除非它是CHOICE类型、开放类型或者一个参数类型。
下面两个定义是等效的:
M DEFINITIONS AUTOMATIC TAGS ::= BEGIN
T ::= SEQUENCE {
a INTEGER, b CHOICE {
i INTEGER, n NULL },
c REAL } END
M DEFINITIONS ::= BEGIN
T ::= SEQUENCE {
a [0] IMPLICIT INTEGER, b [1] EXPLICIT CHOICE {
i [0] IMPLICIT INTEGER, n [1] IMPLICIT NULL },
c [2] IMPLICIT REAL } END
如果使用全局AUTOMATIC TAGS模式时,在描述中给一个类型指定了一个Tag,那么对这个类似的AUTOMATIC TAGS就关闭。如果一个SEQUENCE或者SET类型包含COMPONENTS OF条目,而且这个条目在自动编号前展开;但自动标号又要求在展开前进行,ASN.1编译器要自己检查这种冲突。
对新的协议现在都推荐使用AUTOMATIC TAGS。 2.10.2 SEQUENCE
SEQUENCE是最常用的ASN.1类型之一,它可以嵌套使用,还可以使用OPTIONAL、DEFAULT和COMPONENTS OF等对成员进行修饰。
一个常见的SEQUENCE声明如:
Description ::= SEQUENCE {
surname IA5String, first-name age
}
该类型的一个值为:
johnny Description ::= {
surname first-name
\
\IA5String,
INTEGER
age
}
40
使用OPTIONAL和DEFAULT时,SEQUENCE类型应该能被明确解码,不存在模棱两可的地方。如下这个类型就有问题:
T ::= SEQUENCE {
x y z t
}
在使用BER编码规则时,对于值t1 T::={x 1, y 2, t 3}而言,接收方收到的码流如下: T2L1V1T2L1V2T2L1V3
INTEGER,
INTEGER OPTIONAL, INTEGER DEFAULT 0, INTEGER
Figure 2-6 OPTIONAL引起的歧义 那么在解码过程中,V为2的值无法确定是成员y还是成员z。这种情况下,该类型的定义应该在Tag上做一些补充: T ::= SEQUENCE {
x y z t
}
注意:对于接收方,没有收到声明DEFAULT的成员和收到DEFAULT的值是等价的。
在类型定义中,可以使用COMPONENTS OF将另一个类型的成员插入到当前类型中:
Registration ::= SEQUENCE {
COMPONENTS OF Description, marital-status ENUMERATED
{single, married, divorced,widowed}
INTEGER, -- [UNIVERSAL 2] [0] INTEGER OPTIONAL, [1] INTEGER DEFAULT 0, INTEGER -- [UNIVERSAL 2]
}
COMPONENTS的效果使得上面的定义等效于:
Registration ::= SEQUENCE {
surname first-name age
IA5String,
IA5String,
INTEGER,
marital-status ENUMERATED
{single, married, divorced, widowed}
}
而不是:
Registration ::= SEQUENCE {
description
Description,
marital-status ENUMERATED
{single, married, divorced,widowed}
}
使用COMPONENTS OF的好处在于,如上例中,Description更新升级时,Registration的内容不需要手工修改。
2.10.3 SET
和SEQUENCE相比,SET的成员是没有顺序的。同样可以使用OPTIONAL、DEFAULT和COMPONENTS OF。
2.10.4 SEQUENCE OF
SEQUENCE OF相当于某些语言中的动态数组或者列表:所有成员都是一个类型,数目不定。如:
PariTierce DEFINITIONS ::= BEGIN
SteepleChase ::= SEQUENCE OF INTEGER
END
相应的典型值为:
winningCombination SteepleChase ::= {5, 2, 12} no-one-arrived SteepleChase ::= { }
ASN.1提供一种元标记来编写和描述项目的注释、文档,以“@”开头,后接模块名称、类型名字成员序号或者“*”(表示全部),如:
-- @PariTierce.SteepleChase.* must be distinct
-- @PariTierce.SteepleChase.0 = 5 (horse no. 5 always wins!)
如果是在模块内,则“@”和模块名都可以省略,如:
-- SteepleChase.* must be distinct
-- SteepleChase.0 = 5 (horse no. 5 always wins!)
2.10.5 SET OF
和SEQUENCE OF相比,SET OF的成员是顺序的,其它类似。
2.10.6 CHOICE
CHOICE类型表示一种选择,类似UNION。该提供两个信息:被选择的选项,相应的值。也就是说对于类型:
Afters ::= CHOICE {
cheese dessert
}
它的一个值而言:
mine Afters ::= dessert:\
(注意:表示方法先是选择的选项dessert,而后是“:”,最后是值 ) 没有必要先定义一个枚举类型来表征具体的选项。
和SEQUENCE、SET类型不同,CHOICE没有缺省的UNIVERSAL Tag值,因为它是一些类型的集合,其中被选择项目的Tag会被作为CHOICE相关Tag。在和SEQUENCE、SET一起使用时,要注意使用AUTOMATIC TAGS或者context-specific Tags。如下面,类型U的定义有问题(Tag 0 和 1都重复了两次):
T ::= CHOICE { a [0] INTEGER,b [1] NULL } U ::= SET {
x y z {
c [1] BIT STRING, d [2] OCTET STRING }
}
[0] REAL, T, CHOICE
[0] IA5String, [1] IA5String

