本文共 1956 字,大约阅读时间需要 6 分钟。
本节书摘来自异步社区《精通SNMP》一书中的第2章,第2.4节,作者: 武孟军 更多章节内容可以访问云栖社区“异步社区”公众号查看。
除前面介绍的简单类型和结构类型外,还存在标签类型和子类型,它们是ASN.1从不同应用角度定义的两种类型。
2.4.1 标签类型
一般地,用户在定义类型时,除了名字外,Tag、传输编码都继承基础类型原有的定义。标签类型(Tagged Type )是这样一种类型:用户在利用已有的类型定义新类型时,也为新类型定义了新的Tag。例如下面的类型定义语句:
Age ::= INTEGER
其中,类型Age也是整型类型,Tag、传输编码都不改变。再看下面的类型定义语句:
IpAddress ::= [ APPLICATION 0 ] IMPLICIT OCTET STRING (SIZE (4))
类型IpAddress的基础类型是OCTET STRING,但它的Tag已经不再是基础类型的Tag了,而是新分配了一个。注意,类型IpAddress虽然Tag和OCTET STRING不同,但传输时仍然采用OCTET STRING的编码方式。
当一个应用系统使用ASN.1时,需要定义自己的特定类型。有时,不同类型的基础类型相同。例如,描述人的身高、体重和年龄属性的数据类型,可以是一种数据类型,基础类型是INTEGER;如果认为有必要进一步区分这三种类型,也可以定义成三种不同的类型,并为它们分配新的标志号,从而定义成标签类型。也就是说,虽然三种标签类型的基础类型都是INTEGER,但它们的Tag不同,是三种不同类型,分别用来描述身高、体重和年龄。
另外,在结构类型SET中,不同的组件经常有相同的类型,为了避免混淆,也需要将这些组件定义为标签类型。
标签类型的定义有直接方式(Explicit)和间接方式(Implicit)两种,最常用的是间接方式定义,语法为:
< 类型名 > ::= [ [ 类别名 ] 标志号 ] IMPLICIT < 基础类型 >
方括号中的类别名是可选的,默认是上下文有关类。间接方式定义的标签类型取代了基础类型的Tag,传输时使用新的Tag。
直接方式比较少见,语法为:
< 类型名 > ::= [ [ 类别名 ] 标志号 ] EXPLICIT < 基础类型 >
直接方式是在基础类型的Tag上增加了一个新的类型类别名和标志号,传输时新定义类型的Tag形式是新定义Tag和基础类型的Tag一起使用。
结构类型组件的标签类型的定义方式,可以在模块格式中统一指定,这种方式被称为全局标签类型定义方式。全局定义方式有EXPLICIT TAGS 和IMPLICIT TAGS两种形式,以后的标准中又增加了一种AUTOMATIC TAGS方式。
如果模块中全局标签定义方式为IMPLICIT TAGS,则模块中所有结构类型(CHOICE类型除外)的组件标签定义缺省方式为IMPLICIT,除非显式指定为EXPLICIT方式。此外,全局方式只对本模块中定义的类型起作用,从其他模块中引用的类型标签定义方式不受影响。
2.4.2 子类型
如果类型A的值集合是另一个类型B的值集合的子集,那么类型A称为类型B的子类型。例如,类型定义语句:Subint ::= INTEGER (0 . . 255)
定义类型Subint是INTEGER类型的子类型。
上面语句定义的子类型称为简单子类型,除此之外,还有一种形式复杂的子类型。复杂子类型使用如下的关键字:
SIZE --大小,长度范围 FROM --由限制字符所组成的字符串 INTERSECTION --交集 UNION --并集,与 '|' 相同 EXCEPT --除……之外 ALL --包括……的全部
这些关键字可以组合使用,意义很容易理解,下面是几个具体例子:
INTEGER (ALL EXCEPT (1..20)) --不包括1到20数字的所有整数 IA5String ("yes" UNION "no" UNION "maybe") --或“yes” 或“no” 或 “maybe” PrintableString (FROM ("A"|"B"|"C"|"D")) --字符串中不能出现A、B、C和D之外的字符 PrintableString (SIZE (10)) --长度为10的可打印字符串 PrintableString (SIZE (1..10)) --大小范围在1到10的可打印字符串
转载地址:http://fxdeo.baihongyu.com/