一、ASN.1简介
ASN.1(Abstract Syntax Notation dotone),抽象语法标记1。是定义抽象数据类型形式的标准,描绘了与任何表示数据的编码技术无关的通用数据结构。抽象语法使得人们能够定义数据类型,并指明这些类型的值。抽象语法只描述数据的结构形式,与具体的编码格式无关,同时也不涉及这些数据结构在计算机内如何存放。
二、ASN.1基本语法规则
- 在ASN.1中,符号的 定义没有先后次序,只要能够找到该符号的定义即可,而不必担心在使用它之前是否被定义过。如:
age Age ::= 18 创建Age的实例 Age ::= INTEGER 定义了Age这个类型
- 标识符、参考、关键字都要以一个字母开头,后接字母、数字或者连字符‘-’ 而不是下划线。同时不能以连字符结尾,也不能连续出现两个连字符
- 关键字全部大写
- 在标识符中,只有类型和模块名字是以大写字母开头的,其他标识符都是以小写字母开头
- 字符串有三种形式,具体请参考下面的类型
- 带小数点的小数形式不能在ASN.1中直接使用,ASN.1中实数的实际定义为:尾数、基数和指数
- 注释以**两个连字符“–”**开始,结束于行的末尾或者该行中另一个双连字符
- ASN.1不对空格、制表符、换行符和注释做翻译。但是在定义符号 “::=” 中不能有空格,否则不能正确处理
三、ASN.1中类型
1. 基本类型
类型 | 含义 | 和java对应的数据类型 |
NULL | 只有一个值NULL,用于传送一个报告或者作为CHOICE类型中的值 | null |
INTEGER | 整数类型 | int/Integer |
REAL | 实数,表示浮点数 | double/Double/Float/float |
ENUMERATED | 标识符的枚举(实例状态机的状态) | enum |
BITSTRING | 比特串 | |
OCTETSTRING | 字节串 | |
OBJECT IDENTIFIER,RELATIVE-OID | 一个实体的标识符 | |
EXTERNAL,EMBEDDED PDV | 表示层上下文交换类型 | |
String(除了BITSTRING、OCTETSTRING外) | 各种字符串,有NumericString、PrintableString、VisibleStirng、ISO64String、IA5String、TeletexStirng、T61String、VideotexString、GraphicString、GeneralString、UniversalString、BMPString和UTF8String | |
CHARACTERSTRING | 允许为字符串协商一个明确的字符表 | |
UTCTime,GeneralizedTime | 日期 | Date |
BOOLEAN | 布尔类型 | Boolean/boolean |
2. 组合类型
类型 | 含义 | 和java对应的数据类型 |
CHOICE | 选择类型,该字段可能有多重不同的类型来表示 | |
SEQUENCE | 由不同类型的值组成一个有序的集合 | List |
SET | 无序集合(不同类型的值) | Set |
SEQUENCEOF | 由相同类型的值组成一个有序的集合 | List(存储相同的类型) |
SETOF | 无序集合(相同类型的值) | Set(存储相同类型) |
三、类型的定义及赋值
- <新类型的名字>::= <类型描述>
- <新类型的名字>是一个类型的名字,也可以是类型描述
- <类型描述>基本类型、组合类型
- <新的值的名字><该值的类型> ::= <值描述>
- <新的值的名字>是以小写字母开头的标识符;
- <该值的类型>可以是一个类型的名字,也可以是类型描述;
- <值描述>是基于整数、字符串、标识符的组合
**基本类型-- **1.整数类型-- Age::=INTEGER age AGE::=18 VehicleType::=INTEGER{ car(0), bus(1), taxi(2) } vehicleA VehicleType::=0 **2.布尔类型-- Flag::=BOOLEAN isCheck Flag::=FALSE **3.枚举类型-- Week::=ENUMERATED{ Monday(1), Tuesday(2), Wednesday(3), Thursday(4), FriDay(5), Saturday(6), Sunday(7) } bestWeek::=Saturday **4.实数类型ASN.1对实数的精度没有限制。每个实数可以用M×BE表示,即三元组。{M,B,E}-- AngleInRadians::=REAL pi AngleInRadians::={31415926,10,-7} 即31415926-10^-7=3.1415926 **5.位串类型-- Occupation::=BIT STRING{ clerk (0), editor (1), artist (2), publisher (3), manager(4) } tom Occupation::={editor,artist} **6.字节串类型,八位位组串,由0个或多个8位位组组成的有序串。可用十进制(0-255)。二进制和十六进制表示。如:1101000100011010B或D11AH-- IpAdress::=OCTET STRING(SIZE(6)) ip IpAdress::=11H1D001E001A **7.对象标识符。从对象树派生出的一系列点分数字串的形式,用来表示对象。 object OBJECT IDENTIFIER::={pc(1) mac(2) vm(3) mobile(4)} computer OBJECT IDENTIFIER::={object 1} macComputer OBJECT IDENTIFIER::={object 2} vmComputer OBJECT IDENTIFIER::={object 3} mobilePhone OBJECT IDENTIFIER::={object 4} **8.空值类型:空值类型,当某时刻无法知道数据的标准值,可将值为NUL-- RoomRenter::=SEQUENCE{ name Visiblestring --取自IA5的图形字符组成,不含控制字符 roomNumber CHOICE{ INTEGER NULL } --代表可选项,可是INTEGER或者NULL } roomRenter1 RoomRenter::={name "Tom",roomNumber 301} roomRenter1 RoomRenter::={name "Jerry",roomNumber NULL} **9.字符串类型-- NumString::=NnmericString numStr NumString::="12345678" UserName::=PrintableString user UserName::="Tom" **组合类型-- **SEQUENCE-- AirlineFlight::=SEQUENCE{ airline IA5string, --取自IA5的字符组成,它与ASCII码基本相同 flight Numericstring, --包含数据0到9以及空格,不包含控制字符集 seats SEQUENCE{ --座位 maximum INTEGER, occupied INTEGER, vacant INTEGER }, airport SEQUENCE { --机场 origin IA5string, stop1 [0] IA5string OPTIONAL, stop2 [1] IA5string OPTIONAL, destination IA5string }, crewsize ENUMERATED { --工作人员数目,枚举 six (6), eight (8), ten (10) }, cancle BOOLEAN DEFAULT FALSE --是否取消航班,默认否 } airplane AirlineFlight::={ airline "china", flight "1106", seats {320,280,40}, airport {origin "Beijing", destination "Shanghai"}, crewsize ten } **10.SEQUENCE OF、SET 和SET OF基本类似,可以参考上面的-- **11.标签类型-- Art::=[UNIVERSAL 0] INTEGER art Art ::=9 Gym::=[APPLICATION 1] INTEGER gym Gym::=10 Excont::= SET{ type1 [0] INTEGER OPTIONAL, type2 [1] INTEGER OPTIONAL } **12.CHOICE 选择类型-- Prize::=CHOICE{ car IA5string, cash INTEGER, nothing BOOLEAN } peter Prize::=TRUE 或者 John Prize::= "Lincoln" 或者 Sam Prize::= 25000
四、子类型定义
通过对某些类型加以限制,可以定义它们的子类型(subtype)。
通过对某些类型加以限制,可以定义它们的子类型(subtype)。子 类型的值集合是其父类型值集合的子集。 (1) 单个值 在定义中列举出所有可能的取值 TestResult ::=INTEGER(1|2|3|4) sp1 TestResult ::= 2 (2) 大小限制 通过限制父类型中元素的个数定义新类型或规模。 WorkstationNumber::=OCTET STRING(SIZE(6)) BitField ::= BIT STRING(SIZE(12)) map1 BitField ::= "100110100100"B map2 BitField ::= "9A4"H (3) 取值范围(值区间) 只适用于整数和实数类型, NoID::=INTEGER(1..100) PositiveInteger ::=INTEGER(0<..MAX) PositiveInteger ::=INTEGER(1..MAX) (4) 可用字符 只用于字符串类型,限制字符集的取值范围。 DigitString ::=IA5String(FROM(2)|(3)|(4)|5|(6)|(7)) str2 DigitString ::= "46732" (5) Inner Subtyping (内部类型) 适用于SEQUENCE,SEQUENCE OF,SET,SET OF和CHOICE类,主要用于对 这些结构类型的元素项进行限制。 PDU::=set{ alpha [0] INTEGER, beta [1] IA5striong OPTIONAL, gamma [2] SEQUENCE OF parameter, delta [3] BOOLEAN } TestPDU::=PDU(WITH COMPONENTS{ alpha(min..<0),...,delta(FALSE) }) (6) 包含子类型 要用到关键字INCLUDES,说明被定义的新子类型包含原子类型的全部可能值。 Months::=ENUMERATED{ jaunary(1), february(2), ..., december(12) } First-quarter::=Months(january,february,march); Second-quarter::=Months(april,may,june) First-half::=Months (INCLUDES First-quarter|INCLUDE Second-quarter) jan First-quarter ::= 1 4.2.5 应用类型 ASN.1中的应用类型与特定的应用有关,根据网络管理的实际特点, RFC1155定义了6种SNMP应用类型。 (1) NetworkAddress::=CHOICE{internet IpAddress} --可从各种网络地 址中选择一种,目前只有Internet地址,即IP地址。 (2) IpAddress::=[APPLICATION 0] IMPLICIT OCTET STRING(SIZE(4)) (3) Counter::= [APPLICATION 1] IMPLICIT INTEGER(0..4294967295) (4) Gauge::=[APPLICATION 2] IMPLICIT INTEGER(0..4294967295) (5) TimeTicks::=[APPLICATION 3] IMPLICIT INTEGER(0..4294967295) (6) Opaque::= [APPLICATION 4] OCTET STRING --arbitrary ASN.1 value 不透明类型 4.3 基本编码规则 用ASN.1语言书写的变量必须转换为串行的字节流才能在网络中传输。为此, ASN.1又提供了基本编码规则(BER)来描述传输过程中内容的表示。约定 八位位组:八比特组成 八位位组的二进制位编号从8到1,第8位为最高有效位,第1位位最低有效位 编码结构 标签八位位组 长度八位位组 1. 标签(tag)字段:关于标签类别和编码格式的信息。 2. 长度(Length)字段:定义内容字段的长度。 3. 值(Value)字段:包含实际的数据 。 = 标签号 UNIVERSAL 10 编码:00 0 01010 APPLICATION 35 (构造类型) 编码:01 1 11111 0 0 100011 2. 长度字段 用来表示值字段的八位位组数。 确定格式。(编码时知道长度;长格式和短格式) 长度字段分类 不确定格式。 规则如下: 2.1.若编码是简单类型,则使用确定格式; 2.2.若编码是构造的,并且编码立即可用,既可以使用确定格式,也可以使用不 确定格式,由发送者选择; 2.3.若编码是构造的,但编码不是立即可用,则使用不确定格式。 短格式: L=38 编码:00100110 长格式: L=201 编码: 10000001 11001001 不确定格式:10000000 3. 值字段 由零个或多个八位位组组成,并按不同类型数据值的不同规定对它们进行编 码。 (1) 布尔值的编码 由1个字节组成。FALSE为00;TRUE为FF。 TRUE的编码:01 01 FF FALSE 的编码:01 01 00 (2) 整数编码 值字段一个或多个八位位组组成,整数值采用二进制补码形式编码。 0 编码 02 01 00 127 编码 02 01 7F 256 编码 02 02 01 00 -129 编码 02 02 FF 7F (3) 空值的编码 空值的标签 UNIVERSAL 5, 编码 05 00 (4) 位串值的编码 简单类型 构造类型 (0A3B5F291CD)16 简单类型编码:03 07 04 0A3B5F291CD0 构造类型编码:将位串值拆为(0A3B)16和(5F291CD)16 23 80 03 03 000A3B 03 05 04 5F291CD0 00 00 (5) 对象标识符的编码 对象标识符值的编码是简单类型。 第一个编码子标识符的数值:(X*40)+Y 对象标识符 {joint-iso-ccitt 100 2},即{2,100,3} 编码:06 03 813403 H (6) 八位位组串和字符串类型值的编码 IA5String类型字符串“ACE” 编码 16 03 41 43 45 H 八位位组串“ACE0” 编码 04 02 AC E0 H (7) 序列值的编码 序列值的编码是构造类型。 序列类型{name IAString, ok BOOLEAN},值{name “smith”, ok TRUE} 编码:30 0A 16 05 73 6D 69 74 68 01 01 FF (8) 集合值的编码 集合类型的元素是无序的,有多种编码。 SET{breadth INTEGER, bent BOOLEAN}, 值{breadth 7, bent FALSE} 编码:31 06 02 01 07 01 01 00
六、ASN.1信息对象类和信息对象
<信息对象类>::= CLASS <类描述> WITHSYNTAX <信息描述>
用于表达比注释更为正式的一些信息
七、ASN.1模块定义
<模块名字> DEFINITIONS <缺省Tag>::= BEGIN EXPORTS <导出描述> IMPORTS <导入描述> <模块体描述> END Module2 { isomember-body(2) f(250) type-org(1) ft(16) asn1-book(9)chapter5(0) module2(1) } DEFINITIONS AUTOMATICTAGS ::= BEGIN EXPORTS Type2; IMPORTS Type1, valueFROM Module1 {iso member-body(2) f(250) type-org(1)ft(16) asn1-book(9) chapter5(0) module1(0)}; Type2 ::= SEQUENCE OFChoice Choice ::= CHOICE { a INTEGER (0..value), b Type1 } END
1).AUTOMATICTAGS是指缺省Tag,说明不关注模块的Tag。
2).IMPORTS声明在其它模块定义但在本模块会用到的类型或者值。EXPORT声明在本模块之外可以访问的类型或者值。IMPORTS的语法为:IMPORTS <名字>,value FROM <其它模块的ObjectIdentifier>; EXPORTS的语法为:EXPORTS<名字>;
3).对象标识符(OBJECTIDENTIFIER,OID)类型用层次的形式来表示标准规范。标识符树通过一个点分的十进制符号来定义,这个符号以组织,子部分然后是标准的类型和各自的子标识符开始.