第2章 抽象语法标记
抽象语法标记(ASN.1)是一种数据对象描述标准,包括两部分内容,数据描述语言(CCITT X.208)和数据编码规则(CCITT X.209)。SNMP标准中使用ASN.1定义数据,理解它是深入理解SNMP的基础。
本章和第3章将分别讲述ASN.1的数据描述语言和基本编码规则(Basic Encoding Rules,BER)的内容。
2.1 概述
系统,都有各自独立的一套数据定义和存储格式,因此在处理异种系统之间的通信时,使用哪种数据格式是一件很麻烦的事情。对于这个问题,最有效率的解决方式是,使用一套独立于任何平台和编程语言的数据类型。ASN.1就是专门用来描述这种数据类型的标准语言。
2.1.1 异种系统通信问题
任何一种计算机语言,在描述数据类型时都有一套特定的语法规范。例如,C语言中定义一个整型变量x的语法为:
int x;
在做上述定义时需要遵守C语言定义整型变量的语法,否则编译时会产生语法错误。另外,系统在处理时,需要为变量x分配一块物理内存,用来存储x的值,以便今后对变量x的值可以进行读取或更改等操作。
像这类用计算机语言描述数据类型的语法,它所定义的数据真实存在,我们称其为具体语法(concrete syntax)。
因为每种语言的具体语法不同,因此由该语法定义的数据类型是不适合异种系统之间通信使用的。如果相互通信的系统只有两种,则可以选择某一种系统的数据类型作为双方的交换数据类型,另一种系统将自己的数据类型做转换就可以了。但现实环境中往往有多种不同系统需要相互通信,这种情况下如果做类型转换处理会很复杂。
ASN.1可以“凭空”定义不依赖任何平台的数据类型。任何两种不同系统之间要进行信息交换,可以预先使用ASN.1定义的标准的数据类型,并约定参与通信的各方均使用这种数据类型进行通信。由于ASN.1定义的数据类型主要用于信息交换,因此数据类型都定义了传输编码格式,其中,基本编码规则BER是最常用的一种。参与通信的一方,在数据交换之前,首先对自己的数据进行格式转换、编码处理,然后再发送;相应地,接收方在接收数据后要先进行解码处理。整个通信过程如图2-1所示。
由此可见,ASN.1定义的数据类型在一个系统中物理上是不存在的。它只是一种数据格式,只有在传输时才有意义;它以BER编码格式存在于通信线路中,接收方一旦接收,即刻就将其转换为具体语法定义的数据类型。
正是由于这种数据类型的“抽象”特性,所以描述它的语法在OSI术语中被称为抽象语法(abstract syntax)。抽象语法定义的数据类型,在传输时遵循的数据编码规则,称为传输语法(transfer syntax)。一种ASN.1数据类型对应的传输语法可以有多种,但只能使用其中的一种。
2.1.2 巴柯斯范式
在计算机科学中,巴柯斯范式(Backus Normal Form,BNF)专门用来定义计算机语言。ASN.1标准也是由一系列巴柯斯范式定义的,关于它的所有产生式可参阅附录一。
语法符号定义由一系列的产生式组成,产生式的基本形式如下:
symbol ::= alternative1 | alternative2 …
注意:
产生式中的符号“::=”也可以是符号“→”。
符号“::=”可以解释为“被定义为”,右边的符号可以代替左边的符号,用做替代的符号可以有多个可选项,使用“|”分隔。产生式右边用引号引起来的替代符号为终结符,终结符是出现在语言中的最终符号,不能再被其他符号替换。
产生式中所使用的符号含义如表2-1所示。
使用巴柯斯范式定义的语言,由一系列简单和复杂的产生式组成。运用这些产生式可以生成语言中所有的符号元素。在某种语言中,凡是能够应用该语言的产生式推导出的符号,就是合法符号,否则就是非法字符。
例如,使用下面的产生式生成的S表示所有数字,包括小数、整数和负数。
S ::= '-'FN | FN
FN ::= DL | DL'.'DL
DL ::= D | D DL
D ::='0'| '1'| '2'|'3'|'4'|'5'|'6'|'7'|'8'|'9'
对于第一个产生式来说,如果要产生一个正数,则用选项FN开始,依次使用后面的生成式右端替换,直到全部替换成终结符为止;如果要产生一个负数,则用选项‘-’FN开始,进行一系列替换,直至所有符号变成终结符。
例如,如果要产生数字序列1918,可以通过下列步骤生成:
S ::= FN // 开始;
S ::= DL // DL替换FN;
S ::= D DL // D DL 替换DL;
S ::= D D DL // D DL 替换DL;
S ::= D D D DL // D DL 替换DL;
S ::= D D D D // D 替换DL;
S ::= 1 D D D // 终结符1 替换D;
S ::= 1 9 D D // 终结符9 替换D;
S ::= 1 9 1 D // 终结符1 替换D;
S ::= 1 9 1 8 // 终结符8 替换D;
形如DL ::= D | D DL的产生式会经常遇到,其最终结果经常是DDD……即终结符的一个无穷序列。同样的,产生式DL::= D | D'.'DL的最终结果是D.D.D……注意可选项出现的顺序对结果无影响。
ASN.1中定义的基本类型符号、值符号都有对应的产生式,且很多最终的符号形式不止一种。但无论符号形式如何变化,必须能利用对应的产生式经过一系列替换操作推导出来。