密码学系列之:ASN.1 接口描述语言详解
简介
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 的例子:
上面的例子中,我们使用 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 中的每个属性都指定一个内部的标识符,如下所示:
这里面的[0] [1]
就是标识符,当然,我们可以在定义 module 的时候手动指定这些 tags,但是如果我们使用AUTOMATIC TAGS
,这些标识符会自动创建,从而避免了手动创建标识符可能带来的问题。
ASN.1 中的内置类型
通过上面的讲解,我们对 ASN.1 有了一个基本的概念。如果想要对 ASN.1 进行更加深入的研究,那么我们首先要知道 ASN.1 中的内置类型。
一般来说 ASN.1 中有下面的数据类型:
BOOLEAN
BOOLEAN 和编程语言中的布尔值是一致的,它有两个可能得值:TRUE 和 FALSE。下面是具体而用法:
INTEGER
INTEGER 表示的是一个整数,如下所示,表示的是一个年例范围是 0 到 100,最终的取值是 18:
BIT STRING
字节的位表示方法,可以给一个 byte 中的每一个 bit 进行设值:
上面的例子中,我们设置了 Status,并且使用 Status 赋值给了一个变量 myStatus。
OCTET STRING
8 进制表示的字符串:
DATE
表示日期,格式是"YYYY-MM-DD":
TIME-OF-DAY
表示日期中的时间,格式是"HH:MM:SS":
DATE-TIME
时间加日期的格式,它的格式"YYYY-MM-DDTHH:MM:SS",如下所示:
REAL
REAL 表示的是一个浮点数,可以如下表示:
ENUMERATED
ENUMERATED 表示的是一个枚举,可以如下表示:
SEQUENCE
SEQUENCE 表示的是项目的序列合集,如下所示:
SEQUENCE OF
SEQUENCE OF 表示的是一个 list:
CHOICE
CHOICE 表示从众多的 item 中选择一个:
IA5String
IA5String 表示的是 ASCII 字符,并且包含有控制字符。
VisibleString
VisibleString 表示的是 ASCII 字符,其中不包含有控制字符。
NumericString
NumericString 表示的是数字和空格。
UTF8String
UTF8String 表示的是 Unicode 字符
NULL
是一个空值,用来占位。
ASN.1 中的限制语法
ASN.1 中可以定义很多个字段,有些字段可能会有一些限制,比如手机号只能用数字,名字有长度限制等。
这些限制在 ASN.1 中叫做 Constraints,一般来说有下面的一些限制:
FROM
FROM 提供了一个数据值的读取范围,如下:
PermittedChars 只允许从"ABCDEFG1244"选择。
PATTERN
PATTERN 表示的是正则表达式,如下所示:
上面列出的是一个简单的手机号码的正则表达式。
SIZE
SIZE 可以表示字符串的长度或者数组的长度:
RANGE
使用..
可以表示一个范围:
单一值
从提供的值列表中挑选一个:
总结
以上就是 ASN.1 数据结构描述语言的基本介绍了,有了这些基础,我们就可以很容易读懂使用 ASN.1 来描写的数据结构了。
更多内容请参考 http://www.flydean.com/46-asn-1/
最通俗的解读,最深刻的干货,最简洁的教程,众多你不知道的小技巧等你来发现!
欢迎关注我的公众号:「程序那些事」,懂技术,更懂你!
版权声明: 本文为 InfoQ 作者【程序那些事】的原创文章。
原文链接:【http://xie.infoq.cn/article/61dffcba9e338871a91ddb4db】。文章转载请联系作者。
评论