我正在尝试学习和理解BER(基本编码规则)。
我一直在使用网站http://asn1-playground.oss.com/来试验不同的ASN.1对象并使用BER对它们进行编码。
然而,即使最简单的编码似乎也让我感到困惑。
我们采用一个简单的ASN.1模式:
World-Schema DEFINITIONS AUTOMATIC TAGS ::=
BEGIN
Human ::= SEQUENCE {
name UTF8String
}
END
所以基本上这只是一个SEQUENCE
,只有一个名为name
的UTF8String类型字段。
与此序列匹配的值的示例如下:
{ "Bob" }
因此,使用http://asn1-playground.oss.com/
,我生成以下数据的BER编码:
some-guy Human ::=
{
name "Bob"
}
我希望这会生成一个序列对象,后跟一个字符串对象。
我得到的是:
30 05 80 03 42 6F 62
现在,我理解此编码的一些。第一个八位位组30
是标识符,它告诉我们SEQUENCE
类型是第一个对象。 30
是00110000
二进制,这意味着我们有一个class
0
,一个PC(原始/构造)位1
(意味着构造) ),标签号为10000
(十进制16),表示SEQUENCE
到目前为止一切顺利。下一个值是SEQUENCE
的LENGTH(以字节为单位),即05
。
好的,还是那么好。
但是......在下一个八位位组80
,我 完全混淆了 。那是什么意思???我希望值00001100(对于标签号12,意思是UTF8String。)
80
后面的字节非常简单:03
表示长度为3,而42 6F 62
只是UTF8String值本身,"Bob"
答案 0 :(得分:6)
80是特定于上下文的标记0.请注意,模块开头使用“AUTOMATIC TAGS”。这表明所有SEQUENCE,SET和CHOICE类型都将为其组件以[0]开头的上下文特定标签,并为每个后续组件递增1。这样,在创建消息时,您不必担心标记冲突,尤其是在处理可选或具有DEFAULT值的组件时。如果您将“AUTOMATIC”更改为“EXPLICIT”(我不推荐),您将看到编码时期望的[UNIVERSAL 12]。
请注意,AUTOMATIC TAGS仅适用于SEQUENCE,SET或CHOICE组件上的标签。它不适用于顶级组件,这就是为什么你看到了SEQUENCE的[UNIVERSAL 16],而不是在那里看到特定于上下文的标签。
答案 1 :(得分:1)
80表示特定于上下文的类,基元,标签号0.这是因为您指定了一个AUTOMATIC TAGGING环境,该环境自动为类型 Human中的字段 name 分配了[0]标记