2.8.4 ENUMERATED类型
ENUMERATED类型与INTEGER类型相比, 区别在于: <1>取值是受限制的,没有列出的数值不能使用; <2>数值是不能操作的,只能用于编码;
<3>不用明确指定数值,ASN.1可自动计算相应的数值(从0开始); <4>可以使用扩展,保证和新版本的编码兼容;
<5>是数值关联(显式或者隐式)到标识符,而INTEGER中则是标识符显式关联到数值。
ABRT-diagnostic ::= ENUMERATED {
no-reason-given(1), protocol-error(2),
authentication-mechanism-name-not-recognized(3), authentication-mechanism-name-required(4), authentication-failure(5), authentication-required(6), ... }
不能直接使用数字,如:
abert-diagnostic ABERT-diagnostic ::= 4 -- 错误的!
在使用扩展标记“...”时,需要注意的是,在扩展标记后的成员,其数值必须是升序排列的。
A ::= ENUMERATED {a, b, ..., c(0)} -- 错误: a 和 c 都是0
B ::= ENUMERATED {a, b, ..., c, d(2)} -- 错误: c 和 d 都是2
C ::= ENUMERATED {a, b(3), ..., c(1)} -- 正确: c = 1
和CHOICE、SEQUENCE和SET不同,在使用扩展标记“...”后,增加新成员时,ENUMERATED类型中不需要使用版本标识“[[ ]]”,并且只能有一个扩展标记。
注意事项:
<1>按照ASN.1的语义模型,任意两个ENUMERATED类型都是不兼容的。
<2>当一个ENUMERATED类型被IMPORTS到另一个模块中,则其列表中的标识符也被导入,但只能用于该类型值的赋值。
<3>基本列表(在扩展标识符之前)中的值不需要连续,也不需要排序。 <4>扩展列表(在扩展标识符之后)中的值不需要连续,但需要升序排列。
<5>扩展列表中的值不能和基本列表中的值重复,不论该值是明确指定的,还是缺省计算的。
扩展列表中成员的值必须比该列表中前一个成员的值大。(也就是所谓的升序吧) 表示成员值的必须是数字,不能是标识符。 该类型的UNIVERSAL Tag值为10。 2.8.5 REAL类型
从语义上等效于: SEQUENCE {
mantissa INTEGER (ALL EXCEPT 0), base INTEGER (2|10), exponent INTEGER }
但是REAL类型有自己特定的UNIVERSAL Tag值。 pi REAL ::= {314159, 10, -5}
e REAL ::= {271828128459045235360287, 10, -23} zero REAL ::= 0
注意:实数0不能用三元组的方式给出。
我们用PLUS-INFINITY和MINUS-INFINITY分别表示“正无穷大”和“负无穷大”,这两个也不能用三元组表示。
此外,我们也要注意到ASN.1中的实数只能以2或者10为底(base的约束)。
UNIVERSAL的Tag值为9。 2.8.6 BIT STRING类型
按照ASN.1的定义,BIT STRING长度可以为0。它可以是原始的bit流形式,也可以是布尔向量模型。 1)比特流形式:
pi-decimals BIT STRING ::=
'00100100001111110110101010001000100001 01101000110000100011010011000100110001 100110001010001011100000001101110000'B
pi-decimals BIT STRING ::= '243F6A8885A308D313198A2E0370'H 注意:这种形式下,要考虑大小端的影响。 2)布尔向量模型:
如Figure 2-4所示的权限示意图,当使用不同的比特表示权限时,在ASN.1中可以这样描述:
Rights ::= BIT STRING {
user-read(0), user-write(1), group-read(2), group-write(3), other-read(4), other-write(5) }
group1 Rights ::= { group-read, group-write } 当然,也可以之间用码字来赋值: group2 Rights ::= '0011'B group2 Rights ::= '3'H group3 Rights ::= '001100'B
weird-rights Rights ::= '0000001'B 注意:
命名的比特列表不影响值的声明;
命名的比特列表没有限制,位置也不必连续,也不对类型的长度产生影响。如weird-rights。
以码字赋值时,起始的比特是必须的(最左面的比特),用来定位。后续的0比特无意义。group2和group3 与group1的结果是一样的。
需要对BIT STRING长度进行约束时,可以使用SIZE,如:
RIGHTS ::= BIT STRING (SIZE(6))
和命名INTEGER类型相似,在命名BIT STRING中也不能使用扩展标记“…”。 和OCTET STRING类型一样,可以使用CONTAINING 和ENCODED BY来约束。 UNIVERSAL的Tag值为3。 2.8.7 OCTET STRING类型
与BIT STRING类型类似,但是单位不是比特而是8个比特的八位组。 UNIVERSAL的Tag值为4。 2.8.8 OBJECT IDENTIFIER类型
OBJECT IDENTIFIER类型是对象的唯一标识的集合,这里对象可以是(但不限于): <1>一种抽象语法,一定是在表示层无歧义的注册过(ISO8822);
<2>一种传输语法,一定是注册过,在表示层可以被抽象语法使用(ISO8823-1); <3>一种应用实体(ISO7498-3); <4>一个ASN.1模块;
<5>一种ROSE操作(ISO9072-2); 等等。
我们用注册树来表征所有注册的标识:
Figure 2-5 注册树
OBJECT IDENTIFIER类型就是该注册树所有叶子的路径集合。一个OBJECT
IDENTIFIER类型的值可以是:
internet-id OBJECT IDENTIFIER ::=
{ iso(1) identified-organization(3) dod(6) internet(1) }
francetelecom-id OBJECT IDENTIFIER ::= { iso member-body f(250) type-org(1) ft(16) }
ber-id OBJECT IDENTIFIER ::= { 2 1 1 }
即可以用各叶子的名字,可以用编号,也可以混合使用。 此外,对于多个有相同根名字的值,可以如下定义: ID ::= OBJECT IDENTIFIER
id-edims ID ::= { joint-iso-itu-t mhs-motif(6) edims(7) } id-bp ID ::= { id-edims 11 }
id-bp-edifact-ISO646 ID ::= { id-bp 1 } id-bp-edifact-T61 ID ::= { id-bp 2 } id-bp-edifact-octet ID ::= { id-bp 3 } id-bp-ansiX12-ISO646 ID ::= { id-bp 4 } id-bp-ansiX12-T61 ID ::= { id-bp 5 } id-bp-ansiX12-ebcdic ID ::= { id-bp 6 }
每当一个对象注册到注册树中时,ISO标准ISO9834-1都会对它增加一个相应的文本描述,称之为ObjectDescriptor。如对上面ber-id的ObjectDescriptor为:
ber-descriptor ObjectDescriptor ::= \2.8.9 RELATIVE-OID类型
前面OBJECT IDENTIFIER类型可以看作是对象在注册树中的绝对路径,而RELATIVE-OID类型则是相对路径。其参考基准节点可以是一个OBJECT IDENTIFIER类型的值(动态的),或者是收发双方默认的(静态的)。
RELATIVE-OID可以使用CONSTRAINED BY进行约束。

