ASN语法浅析

ASN.1抽象语法标识

ASN.1概述

    抽象语法表示(标记) ASN.1(Abstract Syntax Notation One )一种数据定义语言,描述了对数据进行表示、编码、传输和解码的数据格式。网络管理系统中的管理信息库(MIB)、应用程序的数据结构、协议数据单元(PDU)都是用ASN.1定义的。

ASN.1优点:

通过如下的独立:

⑴ 独立于机器;

⑵独立于程序语言;

⑶独立于应用程序的内部表示,用一种统一的方式来描述数据结构。

解决如下的不同:
⑴ 程序语言之间数据类型不同
⑵ 不同机器平台之间数据的存储方式不同
不同种类的计算机内部数据表示不同
      比如:IBM为EBCDIC,其它为ASCⅡ;Intel的芯片从右到左计数字节数,而Motorola的芯片则从左到计数字节数。


在任何需要以数字方式发送信息的地方,都可使用ASN.1发送各种形式信息。包括音频、视频、图片、数据等。由于各种系统对数据的定义并不完全相同, 这自然给利用其它系统的数据造成了障碍。表示层就担负了消除这种障碍的任务。表示层如同应用程序和网络之间的翻译官:主要解决用户信息的语法表示问题,即提供统一的、格式化的表示和转换数据服务。数据的压缩、解压、加密、解密都在该层完成。


 ASN.1的基本概念 

ASN.1文本的书写规则(文本约定):

(1) 多个空格和空行等效于一个空格;

(2) 用于表示值和字段的标识符、类型指针(类型名)和模块    名由大小写字母、数字和短线组成;

(3) 标识符以小写字母开头;

(4) 类型指针和模块名以大写字母开头;

(5) ASN.1定义的内部类型全部用大写字母表示;

(6) 关键字(保留字)全部用大写字母表示; (7) 注释以一对短线(- -)开始,以一对短线或行尾结束。

在ASN.1中的符号定义

如下表所示

符号 含义
∷= 定义为,或赋值
| 或、选择、列表选项
- 标签号
-- 符号后跟随注释
{ } 列表的开始和结束
[ ] 标签(TAG)的开始和结束
( ) 子类型的开始和结束
.. 范围

 抽象数据类型 

    ASN.1定义的数据类型有20多种,如表2.1所示。这些数据类型可分为4大类。
  ● 简单类型:由单一成分构成的原子类型;
  ● 构造类型:由两种以上元素构成的数据类型;
  ● 标签类型:由已知类型定义的新类型;
  ● 其他类型:包括CHOICE和ANY两种类型。 


表2.1  ASN.1定义的通用类型

标签 类型 值集合

UNIVERSAL 1 BOOLEAN TRUE, FALSE

UNIVERSAL 2 INTEGER 正数、负数和零

UNIVERSAL 3 BIT STRING 0或者多个比特组成的序列

UNIVERSAL 4 OCTET STRING 0或者多个字节组成的序列

UNIVERSAL 5 NULL 空类型

UNIVERSAL 6 OBJECT IDENTIFIER 对象标识符

UNIVERSAL 7 OBJECT DESCRIPTOR 对象描述符

UNIVERSAL 8 EXTERNAL 外部文件定义的类型

UNIVERSAL 9 REAL 所有实数

UNIVERSAL 10 ENUMERATED 整数值的表,每个整数有一个名字

UNIVERSAL 11~15 为ISO8824保留

UNIVERSAL 16 SEQUENCE, SEQUENCE OF 序列

UNIVERSAL 17 SET, SET OF 集合

UNIVERSAL 18 NumericString 数字0~9和空格串

UNIVERSAL 19 PrintableString 可打印字符串

UNIVERSAL 20 TeletexString 由CCITT T.61建议定义的字符集

UNIVERSAL 21 VideotexString 由CCITT T.100/T.101建议定义的字符集

UNIVERSAL 22 IA5String 国际标准字符集(相当于ASCII码)

UNIVERSAL 23 UTCTime 时间码

UNIVERSAL 24 GeneralizedTime 时间码

UNIVERSAL 25 GraphicString 由ISO8824定义的字符集

UNIVERSAL 26 VisibleString 由ISO646定义的字符集

UNIVERSAL 27 GeneralString 通用字符集

UNIVERSAL 28-- 为ISO8824保留

1. 简单类型  

 表2.1中除了UNIVERSAL16和UNIVERSAL17之外都是简单类型。可以用这些类型构造新的数据类型。简单类型分为4组。第一组包括:
    BOOLEAN       布尔类型 
    INTEGER       整型
    BIT STRING       0 个或多个比特组成的字符串类型 
    OCTET STRING   0个或多个字节组成的字符串类型 
    REAL 实数
    ENUMERATED 枚举

这一组叫做基本类型。

  第二组包括各种字符串类型,标签为UNIVERSAL 18~22和UNIVERSAL 25~27,这些类型都可以看作是OCTET STRING类型的子集。 

第三组包括两个类型:
  OBJECT IDENTIFIER     称为对象标识符
  Object Descriptor     称为对象描述符
  对象类型泛指网络中传输的任何信息对象,例如标准文档、抽象语法和传输语法、数据结构和管理对象等都可以看成信息对象。 OBJECT IDENTIFIER类型的值是一个对象标识符,由一个整数序列组成,它惟一地标识一个对象。比如,internet OBJECT IDENTIFIER∷=1.3.6.1或{iso⑴org⑶dodz⑹ 1}   Object Descriptor: 描述信息对象的语义 

第四组包含4种类型。

NULL:是空类型,它没有值,只占用结构中的一个位置,该 位置可能出现或不出现数据;

EXTERNAL:是外部类型,即标准之外的文档定义的类型;

UTCTime:时间类型;

GeneralizedTime:时间的类型。   注:两个时间类型的区别是表示时间的形式不同。

2. 构造类型

构造类型有序列和集合两种
序列类型  ⑴ SEQUENCE:每个元素的类型不相同   ⑵ SEQUENCE OF: 每个元素的类型相同
集合类型  ⑴ SET: 每个元素的类型不相同   ⑵ SET OF: 每个元素的类型相同 序列和集合的区别是前者的元素是有序的,而后者是无序的。    

定义SET和SET OF的语法是类似的:
SetType::=SET {ElementTypeList} | SET {}
SetOfType::=SET OF Type | SET 

类型定义举例

一、字符串类型定义举例:
1、LanWorkstationSerialNumbers::=OCTET STRING(SIZE(32))
2、LanSegment::=SET OF LanWorkstationSerialNumbers
3、MacAddresses::=OCTET STRING(SIZE(6))
4、EthernetNetworks::= SET OF MacAddresses

二、整数型与布尔型
1、Number ::=INTEGER
      abcd Number ::= 696
2、Married ::= BOOLEAN
      tom Married ::= true


三、对象标识符
1、internet  OBJECT  IDENTIFIER ::= { iso(1) org(3)dod(6) 1 }


四、枚举型类型的定义
1、 Week ::=ENUMERATED 
                 {   Monday     (1),
                    Tuesday      (2),
                    Wednesday  (3),
                    Thursday     (4),    
                    Friday          (5),
                    Saturday       (6),
                    Sunday         (7)   }


2、  对于SNMP的MIB,在获取响应信息中的错误状态如下所示:
ErrorStatus::= ENUMERATED        {     noError           (0),
                 tooBig             (1),
                  noSuchname   (2),
                  badValues        (3),
                  readOnly          (4),
                  genError           (5)    }

五、序列类型定义
序列类型定义实例
  SampleType::=SEQUENCE
 {
      name      OCTECT STRING,
      married   BOOLEAN,
      age       INTEGER
  }
序列类型赋值实例
sample SampleType::=SEQUENCE 

{
      name       Mary,
      married    TRUE,
      age        28   

}

一个复杂例子
AirlineFlight ::=SEQUENCE {
                airline IA5STRING,
                flight     IA5STRING,
                seats     SEQUENCE {
                              maximum   INTEGER,
                                  occupied   INTEGER,
                                  vacant     INTEGER   },
                airport   SEQUENCE {
                                  origin   IA5STRING,
                                  stop[0]   IA5STRING OPTIONAL,
                                  stop[1]   IA5STRING OPTIONAL,
                                  destination   IA5STRING    },                         

                crewsize  ENUMERATED {
                                      six     (6),
                                      eight  (8),
                                      ten     (10)                               },
                cancel  BOOLEAN  DEFAULT  FALSE   
          }


一个实例
airplane1  AirlineFlight ::= { 

airline "china",
                flight  "C3416",
                seats  {320 ,280,40},
                airport { original "Qingdao",stop[0] "TaiYuan",destination "WuLuMuQi"},
                crewsize  10

         }
   

上面的实例描述的是从青岛飞往乌鲁木齐的C3416航班,需要机组人员10人,飞机有320个座位,其中有乘客的座位和空座位分别是280个和40个。本次航班需要在太原停机一次。由于cancel使用了默认值FALSE,所以该航班没有取消。


六、集合类型举例
Student ::=SET {
        number   INTEGER,
name       IA5STRING,
age         INTEGER,
gender     ENUMERATED { male(0),female(1) },
major     IA5STRING
}   

  student1 Student ::= {

20040320,
                “LiYong”,
                19,
                 {0},                                    
"Network" }
  

student2 Student ::={
20040720,
“WangHua”,
20,
{1}
                 “ComputerApplication”},

它们都属于Student类型的一个实例。


标签类型

在ASN.1中,每一个数据类型都有一个标签(Tag),标签有类型和值(见表2.1),类型的标签作为数据传输时接收方判断数据类型的依据。 标签的类型分为以下4种:
通用标签:用关键字UNIVERSAL表示,带有这种标签的数据类型是由标准定义的,适用于任何应用;
应用标签:用关键字APPLICATION表示,是由某个具体应用定义的类型;
上下文专用标签:用[]中加一个序数表示,这种标签在文本的一定范围(例如一个结构)中适用;
私有标签:用关键字PRIVATE表示,这是用户定义的标签。

ASN.1的所有类型都带有标签,所谓的标签类型,是指应用或用户加在某个类型上的标签。标签用于区分不同的类型,免得在数据传送时产生异议。比如:
一个结构类型(序列或集合)中,可以用上下文专用标签区分类型相同的元素。例如集合中有3个同样类型的元素,一个指本人的名字,一个指父亲的名字,另一个指母 亲的名字,分别为其指定不同的上下文专用标签[1]、[2]和[3]以示区别,参见下例: 

Parentage::=SET {
SubjectName[1] IMPLICIT IA5String,
MotherName [2] IMPLICIT IA5String OPTIONAL,
FatherName [3] IMPLICIT IA5String OPTIONAL

标签类型分为:隐含或明示,分别用关键字IMPLICIT和EXPLICIT(可省略)表示。    隐含标签的语义是用新标签替换老标签。因此,编码时只编码新标签。   比如,上例 中集合元素:MotherName 被定义为字符串类型 IA5String ,并且加了上下文标签[2]。由于IMPLICIT表示隐含,因此编码时只编码上下文标签[2],不必编码字符串类型 IA5String的标签: UNIVERSAL 22。其余两个意义相同。

明示标签的语义是在一个基类型上加上新标签,从而导出一个新类型。因此在编码时或传送时,新老标签都要编码或传送。可见明示标签产生较长的编码,隐含标签产 生较短的编码。若为了减少传输量和编码量,则就要采用隐含标签

其他类型

CHOICE和ANY 
CHOICE:选择类型,包含一个可供选择的数据类型列表,可以从中选择一个类型作为它的数据类型。定义CHOICE类型的例子:
 

类型定义
    Prize ::= CHOICE {
        car        IA5STRING,
                cash      INTEGER,
                nothing BOOLEAN           }

类型实例
    prize Prize::=CHOICE{
car “Lincoln” ,
            cash 25000,
            nothing TRUE  }


  ANY:类型表示任意类型的任意值。若在定义数据时不能确定数据的类型,可以使用ANY类型。比如:
   

Book::=SEQUENCE{
        author     IA5STRING,
                reference  ANY,
                }
   

 { author “Martin” ,reference  IA5STRING "ISBN007895"} 和 { author “Martin”,reference  INTEGER  1998} 都是Book的正确实例。

CHOICE和ANY,它们是类型未定的类型,值是未定的,所以是两个没有标签的类型。当这种类型的变量被赋值时,它们的类型和标签才确定。


子类型

  子类型是由限制父类型的值集合而导出的类型,因此子类型的值集合是父类型的子集。子类型还可以再产生子类型。产生子类型的方法有6种,如表2.2所示。 

类型 单个值 包含子类型 值区间 限制大小 可用字符 内部子类型

BOOLEAN yes yes

INTEGER yes yes yes

ENUMERATED yes yes

REAL yes yes yes

OBJECT IDENTIFIER yes yes

BIT STRING yes yes yes

OCTET STRING yes yes yes

CHARACTER STRING yes yes yes yes

SEQUENCE yes yes yes

SEQUENCE OF yes yes yes yes

SET yes yes yes

SET OF yes yes yes yes

ANY yes yes

CHOICE yes yes yes


1.单个值
  这种方法就是列出子类型可取的各个值。例如,我们可以定义小素数为整数类型的子集:  SmallPrime::=INTEGER(2|3|5|7|11|13|15|17|19|23|29)
  另外,如果定义Months为枚举类型:
Months::=ENUMERATED{january(1),february(2),march(3),april(4),may(5),june(6),july(7),august(8),september(9),october(10),november(11),december(12)} 

则可以定义First-quarter和Second-quarter
  为Months的子类型:
First-quarter::= Months(january,february,march)
Second-quarter::= Months(april,may,june) 

2. 包含子类型
  这里要用到关键字INCLUDES,说明被定义的类型包含了已有类型的所有的值。例如下面的定义:
  First-half::=Months(INCLUDES First-quarter |  I INCLUDES Second-quarter)
  另外,也可以直接列出被包含的值,例如
  First-third::=Months(INCLUDES First-quarter | april) 

3. 值区间
这种方法只能应用于整数和实数类型,指出子类型可取值的区间。区间可以是闭区间或开区间。如果是开区间,则加上符号“<”。比如:

PositiveInteger::=INTEGER(0<..PLUS-INFINITY)
PositiveInteger::=INTEGER(1..PLUS-INFINITY)      表示该变量的值可以是任意的正整数据
        EmployeeNumber::=INTEGER(1000..20000)
        表示该变量取整数值,范围为1000至20000     

4. 可用字符
这种方法只能用于字符串类型,限制可使用的字符集。下面是两个限制可用字符的例子:
TouchToneButtons::=IA5String(FROM("0"|"1"|"2"|"3"| "4"| "5"|"6"|"8"|"9"|"*"|"#") SIZE(5))
表示该变量可取的值是5个字符组成的字符串。
5. 限制大小
  可以对5种类型限制其规模大小(BIT STRING,OCTET STRING,CHARACTER STRING,SEQUENCE OF,SET OF)限制其规模大小。例如,限制比特串、字节串或字符串的长度,限制构成序列或集合的元素(同类型)个数等。比如:
  WorkstationNumber::=OCTET STRING(SIZE(32))
  表示该变量的值为32个字节的串。

6. 内部子类型

适用于SEQUENCE,SEQUENCE OF,SET,SET OF和CHOICE类型,主要用于对这些结构类型的元素项进行限制。下面用例子说明。假定有一种协议数据单元:
PDU::=SET{ 

alpha[0] INTEGER,
beta [1] IA5String OPTIONAL,
gamma[2] SEQUENCE OF Parameter,
delta[3] BOOLEAN } 

数据结构示例

  下面是取自CCITT(国际电信电报咨询委员会) X.208的一个数据结构示例。 图2.2(a)是关于个人记录的描述,其中包括姓名、头衔、雇员编号、雇佣日期、配偶姓名和子女数等6项信息,而且对每个子女也要给出姓名和出生日期。
  图2.2(b)是用ASN.1描述个人记录的抽象语法。

PersonalRecord::=[APPLICATION 0]IMPLICIT SET
{
Name,

title [0]VisibleString,
number EmployeeNumber,
dateOfHire [1]Date,
nameOfspous [2]Name,
children [3]IMPLICIT SEQUENCE OF ChildInformation DEFAULT

}

ChildInformation::=SET
{
Name,

dateOfBirth [0]Date
}

Name:=[APPLICATION 1]IMPLICIT SEQUENCE
{
givenName VisibleString,
initial VisibleString,
familyName VisibleString
}

EmployeeNumber::=[APPLICATION 2]IMPLICIT INTEGER
Date::=[APPLICATION 3]IMPLICIT VisibleString --YYYYMMDD

其中对雇员编号的定义为
  EmployeeNumber::=[APPLICATION 2]IMPLICIT INTEGER 

其中,EmployeeNumber被定义为整数类型,而且加上了应用标签APPLICATION 2。IMPLICIT表示隐含的,因此编码时只编码应用标签,不必编码整数类型的标签UNIVERSAL 2。对Date类型也一样,注释YYYYMMDD提示了日期的书写格式。
  Name是序列类型,由3个元素组成,各个元素的名字分别为givenName、initial和 familyName。ChildInformation是集合类型,其中的第一个元素没有名字,只有类型。 第二个元素的名字为dateOfBirth,其类型为Date。Date类型还出现在PersonnelRecord的定义中,在这两个地方被分别赋予上下文专用的标签[0]和[1]。 

  个人记录的整体结构被定义为含有6个元素的集合,该集合的最后一个成分为同类型元素的序列,默认值为空序列。ASN.1不仅提供了表示数据结构的手段,而且给出了表示抽象数据类型值的方法,图2.2(c)表示出个人记录的一个具体值。 

个人记录的一个值

{

{givenName "John", initial "P", familyName "Smith"},
title "Director"
number 51
dateOfHire "19710917",
nameOfSpouse {givenName "Mary", initial "T", familyName "Smith"},
children {{{givenName "Ralph", initial "T", familyName "Smith"}, dateOfBirth "20000717"},
 {{givenName "Susan", initial "B", familyName "Smith"}, dateOfBirth "20001111"}}
}


模块定义   

模块(module)是ASN.1的基本构造单位,类似于C语言中的结构,是由一组类型定义和值定义组成的。比如,一个企业可以定义一个模块,一个协议可以定义一个模块,一个协议中的某个功能也可以定义成一个模块。模块定义的基本形式为:

<moduleIdentifier> DEFINITIONS ::=
  BEGIN
EXPORTS
          --定义本模块中可以被其它模块引用的内容
IMPORTS
          --定义本模块中引用其它模块中的内容
      AssignmentList

--模块定义的所有类型、值和宏定义
   END 

例子:

RFC1156-MIB DEFINITIONS ::= 

BEGIN

IMPORTS
      mgmt, NetworkAddress, IpAddress,Counter, Gauge, TimeTicks FROM RFC1155-SMI, OBJECT-TYPE FROM RFC-1212;

   mib          OBJECT IDENTIFIER ::= {mgmt 1}
system       OBJECT IDENTIFIER ::= { mib 1 }
interfaces   OBJECT IDENTIFIER ::= { mib 2 }
at           OBJECT IDENTIFIER ::= { mib 3 }

      ip           OBJECT IDENTIFIER ::= { mib 4 }
      icmp         OBJECT IDENTIFIER ::= { mib 5 }
      tcp          OBJECT IDENTIFIER ::= { mib 6 }
      udp          OBJECT IDENTIFIER ::= { mib 7 }
      egp         OBJECT IDENTIFIER ::= { mib 8 }
……         

END


  LanNetworkModule{iso org dod internet private enterprises Xenterprises 95}
DEFINITIONS EXPLICIT TAGS::=
  BEGIN
    EXPORTS
      LanNetworkName::=SEQUENCE OF RelativeDistinguishedName --End of EXPORTS
    

IMPORTS 
  RelativeDistinguishedName FROM InformationFramework {ioint-iso-ccitt Ds(5) modules(1) informationFramework(1)} --End of IMPORTS


MacAddresses::=OCTET STRING(SIZE(6))
    LanWorkstationSerialNumbers::= OCTET STRING(SIZE(32))
    LanSegment::=SET OF LanWorkstationSerialNumbers
    EthernetNetworks::=SET OF MacAddresses
    TokenRingNetworks::=SET OF LanSegment
    LanNetwork::=SET
       

etherNet [0] IMPLICIT EthernetNetworks,
          tokenNet [1] IMPLICIT TokenRingNetworks
}  

END 



你可能感兴趣的:(数据结构,String,object,Integer,application,Descriptor)