gpt4 book ai didi

tags - 我需要一个例子来理解 ASN.1 中的隐式标记

转载 作者:行者123 更新时间:2023-12-01 18:20:42 26 4
gpt4 key购买 nike

我一直在学习以下教程

http://www.obj-sys.com/asn1tutorial/node12.html

你能通过一个例子帮助我理解隐式标记吗?

最佳答案

在 ASN.1 中,标签实际上有两个目的:打字和命名。打字意味着它告诉编码器/解码器是什么类型的数据类型(它是字符串、整数、 bool 值、集合等),命名意味着如果有多个相同类型的字段和一些(或所有这些)是可选的,它告诉编码器/解码器该值是哪个字段。

如果将 ASN.1 与 JSON 进行比较,您会看到以下 JSON 数据:

"Image": {
"Width": 800,
"Height": 600,
"Title": "View from 15th Floor"
}

您会注意到,在 JSON 中,每个字段总是显式命名(“图像”、“宽度”、“高度”、“标题”)并显式或隐式键入(“标题”是一个字符串,因为它的值由引号,“宽度”是一个整数,因为它没有引号,只有数字,它不是“空”、“真”或“假”,也没有小数点)。

在 ASN.1 中,这条数据将是:
Image ::= SEQUENCE { 
Width INTEGER,
Height INTEGER,
Title UTF8String
}

这将在没有任何特殊标记的情况下工作,这里只需要通用标记。 Universal tags不要命名数据,它们只是输入数据,所以 en-/decoder 知道前两个值是整数,最后一个是字符串。第一个整数是 Width 第二个是 Height 不需要在字节流中编码,它是由它们的顺序定义的(序列有固定的顺序,集合没有。在你提到的页面上,集合是正在使用)。

现在更改架构如下:
Image ::= SEQUENCE { 
Width INTEGER OPTIONAL,
Height INTEGER OPTIONAL,
Title UTF8String
}

好的,现在我们有一个问题。假设接收到以下数据:
INTEGER(750), UTF8String("A funny kitten")

什么是750?宽度还是高度?可能是 Width(缺少 Height),也可能是 Height(缺少 Width),两者看起来都与二进制流相同。在 JSON 中,因为每条数据都被命名,所以很清楚,而在 ASN.1 中则不然。现在仅仅一个类型是不够的,现在我们还需要一个名字。这就是非通用标签进入游戏的地方。将其更改为:
Image ::= SEQUENCE { 
Width [0] INTEGER OPTIONAL,
Height [1] INTEGER OPTIONAL,
Title UTF8String
}

如果您收到以下数据:
[1]INTEGER(750), UTF8String("A funny kitten")

您知道 750 是高度而不是宽度(根本就没有宽度)。在这里,您声明了一个新标签(在这种情况下是特定于上下文的标签),它有两个用途:它告诉编码器/解码器这是一个整数值(键入),并告诉它哪个整数值是(命名)。

但是隐式标记和显式标记之间有什么区别?区别在于隐式标记只是命名数据,en-/decoder 需要 隐式知道该名称的类型 , 而显式标记名称和 显式输入数据 .

如果标记是明确的,数据将被发送为:
[1]INTEGER(xxx), UTF8String(yyy)

因此,即使解码器不知道 [1] 表示高度,它也知道字节“xxx”将被解析/解释为整数值。显式标记的另一个重要优点是将来可以在不更改标记的情况下更改类型。例如。
Length ::= [0] INTEGER

可以改为
Length ::= [0] CHOICE { 
integer INTEGER,
real REAL
}

标签 [0] 仍然表示长度,但现在长度可以是整数或浮点值。由于类型是显式编码的,解码器将始终知道如何正确解码值,因此这种变化是向前和向后兼容的(至少在解码器级别,不一定在应用程序级别向后兼容)。

如果标记是隐式的,数据将被发送为:
[1](xxx), UTF8String(yyy)

不知道 [1] 是什么的解码器将不知道“xxx”的类型,因此无法正确解析/解释该数据。与 JSON 不同,ASN.1 中的值只是字节。所以“xxx”可能是一个、两个、三个或四个字节,如何解码这些字节取决于它们的数据类型,数据流本身没有提供。同样改变 [1] 的类型肯定会破坏现有的解码器。

好的,但是为什么有人会使用隐式标记?总是使用显式标记不是更好吗?使用显式标记时,还必须在数据流中对类型进行编码,这将需要每个标记两个额外的字节。对于包含数千(甚至数百万)标签的数据传输,其中每个字节都很重要(连接速度非常慢、数据包很小、数据包丢失率高、处理设备非常弱)并且双方无论如何都知道所有自定义标签,为什么要浪费带宽,用于编码、传输和解码不必要的类型信息的内存、存储和/或处理时间?

请记住,ASN.1 是一个相当古老的标准,它旨在在网络带宽非常昂贵且处理器比今天慢数百倍的时候实现高度紧凑的数据表示。如果你看看今天所有的 XML 和 JSON 数据传输,甚至考虑为每个标签节省两个字节似乎是荒谬的。

关于tags - 我需要一个例子来理解 ASN.1 中的隐式标记,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3296761/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com