简介
ASN.1 是一种跨平台的数据序列化的接口描述语言。可能很多人没有据说过 ASN.1, 然而置信有过跨平台编程教训的同学可能都听过 protocol buffers 和 Apache Thrift, 尽管 ASN.1 和下面两个语言相比不是那么闻名,然而 ASN.1 的呈现要比他们早的多, 早在 1984 年 ASN.1 就呈现了。
和他们相比 ASN.1 并没有提供繁多的开源实现,而是作为一种标准来供第三方供应商实现的。ASN.1 次要用在定义各种根底协定中,比方罕用的 LDAP,PKCS,GSM,X.500 等。
ASN.1 是一种和平台、语言无关的描述语言,能够应用很多 ASN.1 的翻译工具,将 ASN.1 翻译成为 C, C++, Java 等代码。
ASN.1 的例子
既然 ASN.1 是一个描述语言,那么咱们先来看一个直观的例子。ASN.1 的根底是 module, 咱们看一下 ASN.1 中 module 的例子:
StudentCards DEFINITIONS AUTOMATIC TAGS ::= BEGIN
StudentCard ::= SEQUENCE {
dateOfBirthday DATE,
student StudentInfo
}
StudentInfo ::= SEQUENCE {studentName VisibleString (SIZE (3..50)),
homeAddress Address,
contactPhone NumericString (SIZE (7..12))
}
Address::= SEQUENCE {street VisibleString (SIZE (5 .. 50)) OPTIONAL,
city VisibleString (SIZE (2..30)),
state VisibleString (SIZE(2) ^ FROM ("A".."Z")),
zipCode NumericString (SIZE(5 | 9))
}
END
下面的例子中,咱们应用 ASN.1 定义了一个 StudentCard,最外层的以 BEGIN 和 END 突围的就是 module。StudentCards 是 module 的名字,首字母必须大写。
其中 ::=
是一个赋值符号。
module 中能够有多个 type, type 的名字也必须首字母大写,例如下面的 StudentCard,StudentInfo 等等。
每个 type 中定义了它的组成组件,组件的名字首字母必须小写,这些组件的名字又叫做 identifiers。
下面的 dateOfBirthday 前面接的 DATE 是 ASN.1 中内置的类型。而 student 前面的 StudentInfo 是一个自定义类型,并且同样蕴含在 module 中。
StudentInfo 中的 studentName 是一个 VisibleString,这个 String 的限度是 size 在 3 到 50 之间。
下面咱们定义 module 的时候在 module 前面加上了AUTOMATIC TAGS
,这是什么意思呢?
在 ASN.1 中,tags 是 ASN.1 音讯中每个组件的外部标识符,以 Address 为例,咱们心愿给 Address 中的每个属性都指定一个外部的标识符,如下所示:
Address::= SEQUENCE {street [0] VisibleString (SIZE (5 .. 50)) OPTIONAL,
city [1] VisibleString (SIZE (2..30)),
state [2] VisibleString (SIZE(2) ^ FROM ("A".."Z")),
zipCode [3] NumericString (SIZE(5 | 9))
}
这外面的[0] [1]
就是标识符,当然,咱们能够在定义 module 的时候手动指定这些 tags,然而如果咱们应用AUTOMATIC TAGS
,这些标识符会主动创立, 从而防止了手动创立标识符可能带来的问题。
ASN.1 中的内置类型
通过下面的解说,咱们对 ASN.1 有了一个根本的概念。如果想要对 ASN.1 进行更加深刻的钻研,那么咱们首先要晓得 ASN.1 中的内置类型。
一般来说 ASN.1 中有上面的数据类型:
- BOOLEAN
BOOLEAN 和编程语言中的布尔值是统一的,它有两个可能得值:TRUE 和 FALSE。上面是具体而用法:
removed BOOLEAN ::= TRUE
- INTEGER
INTEGER 示意的是一个整数,如下所示, 示意的是一个年例范畴是 0 到 100,最终的取值是 18:
age INTEGER (0..100) ::= 18
- BIT STRING
字节的位示意办法,能够给一个 byte 中的每一个 bit 进行设值:
Status ::= BIT STRING {married(0),
handsome(1),
kind(2)
}
myStatus Status ::= {handsome, kind}
下面的例子中,咱们设置了 Status,并且应用 Status 赋值给了一个变量 myStatus。
- OCTET STRING
8 进制示意的字符串:
octetExample ::= OCTET STRING
- DATE
示意日期,格局是 ”YYYY-MM-DD”:
birthday DATE ::= "1990-11-18"
- TIME-OF-DAY
示意日期中的工夫, 格局是 ”HH:MM:SS”:
startTime TIME-OF-DAY ::= "09:30:00"
- DATE-TIME
工夫加日期的格局,它的格局 ”YYYY-MM-DDTHH:MM:SS”,如下所示:
endTime DATE-TIME ::= "2022-01-10T18:30:23"
- REAL
REAL 示意的是一个浮点数,能够如下示意:
Amount ::= REAL
- ENUMERATED
ENUMERATED 示意的是一个枚举,能够如下示意:
Colors ::= ENUMERATED {black, red, white}
myColor Colors ::= white
- SEQUENCE
SEQUENCE 示意的是我的项目的序列合集, 如下所示:
StudentInfo ::= SEQUENCE {
name VisibleString,
phone NumericString
}
max StudentInfo ::= {name "J.Max", phone "18888888888"}
- SEQUENCE OF
SEQUENCE OF 示意的是一个 list:
breakTimes SEQUENCE OF TIME-OF-DAY ::= {"10:00:00", "12:00:00", "14:45:00"}
- CHOICE
CHOICE 示意从泛滥的 item 中抉择一个:
Identity ::= CHOICE {
name VisibleString,
phone VisibleString,
idCard VisibleString
}
jack Identity ::= name: "jack"
- IA5String
IA5String 示意的是 ASCII 字符,并且蕴含有控制字符。
SampleString ::= IA5String
- VisibleString
VisibleString 示意的是 ASCII 字符,其中不蕴含有控制字符。
SampleString ::= VisibleString
- NumericString
NumericString 示意的是数字和空格。
SomeNumber ::= NumericString
- UTF8String
UTF8String 示意的是 Unicode 字符
UnicodeString ::= UTF8String
- NULL
是一个空值,用来占位。
ASN.1 中的限度语法
ASN.1 中能够定义很多个字段,有些字段可能会有一些限度,比方手机号只能用数字,名字有长度限度等。
这些限度在 ASN.1 中叫做 Constraints, 一般来说有上面的一些限度:
- FROM
FROM 提供了一个数据值的读取范畴,如下:
PermittedChars ::= IA5String (FROM("ABCDEFG1244"))
PermittedChars 只容许从 ”ABCDEFG1244″ 抉择。
- PATTERN
PATTERN 示意的是正则表达式,如下所示:
phoneNumber ::= IA5String (PATTERN "1[0-9]#10")
下面列出的是一个简略的手机号码的正则表达式。
- SIZE
SIZE 能够示意字符串的长度或者数组的长度:
Name ::= IA5String (SIZE (4..7))
NameList ::= SEQUENCE SIZE (1..25) OF Name
- RANGE
应用 ..
能够示意一个范畴:
Age ::= INTEGER (0..100)
- 繁多值
从提供的值列表中筛选一个:
Colors ::= UTF8String ("Blue" | "White")
总结
以上就是 ASN.1 数据结构描述语言的根本介绍了,有了这些根底,咱们就能够很容易读懂应用 ASN.1 来刻画的数据结构了。
更多内容请参考 http://www.flydean.com/46-asn-1/
最艰深的解读,最粗浅的干货,最简洁的教程,泛滥你不晓得的小技巧等你来发现!
欢送关注我的公众号:「程序那些事」, 懂技术,更懂你!