且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

《精通SNMP》——第2章 抽象语法标记2.1 概述

更新时间:2022-09-15 20:33:30

本节书摘来自异步社区《精通SNMP》一书中的第2章,第2.1节,作者: 武孟军 更多章节内容可以访问云栖社区“异步社区”公众号查看。

第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所示。


《精通SNMP》——第2章 抽象语法标记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所示。


《精通SNMP》——第2章 抽象语法标记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中定义的基本类型符号、值符号都有对应的产生式,且很多最终的符号形式不止一种。但无论符号形式如何变化,必须能利用对应的产生式经过一系列替换操作推导出来。