我需要一个例子来理解 ASN.1 中的隐式标记 [英] I need an example to understand Implicit Tagging in ASN.1

查看:33
本文介绍了我需要一个例子来理解 ASN.1 中的隐式标记的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我一直在学习以下教程

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

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

Can you help me understand implicit tagging with an example?

推荐答案

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

In ASN.1 tagging, in fact, serves two purposes: typing and naming. Typing means it tells an en-/decoder what kind of data type that is (is it a string, an integer, a boolean, a set, etc.), naming means that if there are multiple fields of the same type and some (or all of them) are optional, it tells the en-/decoder for which field that value is.

如果将 ASN.1 与 JSON 进行比较,并查看以下 JSON 数据:

If you compare ASN.1 to, let's say, JSON, and you look at the following JSON data:

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

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

You'll notice that in JSON every field is always explicitly named ("Image", "Width", "Height", "Title") and either explicitly or implicitly typed ("Title" is a string, because its value is surrounded by quotes, "Width" is an integer, because it has no quotes, only digits, it's not "null", "true" or "false", and it has no decimal period).

在 ASN.1 中,这条数据是:

In ASN.1 this piece of data would be:

Image ::= SEQUENCE { 
    Width  INTEGER,
    Height INTEGER,
    Title  UTF8String
 }

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

This will work without any special tagging, here only the universal tags are required. Universal tags don't name data, they just type data, so en-/decoder know that the first two values are integers and the last one is a string. That the first integer is Width and the second one is Height doesn't need to be encoded in the byte stream, it is defined by their order (sequences have a fixed order, sets don't. On the page you referred to sets are being used).

现在更改架构如下:

Image ::= SEQUENCE { 
    Width  INTEGER OPTIONAL,
    Height INTEGER OPTIONAL,
    Title  UTF8String
 }

好的,现在我们遇到了问题.假设收到如下数据:

Okay, now we have a problem. Assume that the following data is received:

INTEGER(750), UTF8String("A funny kitten")

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

What is 750? Width or Height? Could be Width (and Height is missing) or could be Height (and Width is missing), both would look the same as a binary stream. In JSON that would be clear as every piece of data is named, in ASN.1 it isn't. Now a type alone isn't enough, now we also need a name. That's where the non-universal tags enter the game. Change it to:

Image ::= SEQUENCE { 
    Width  [0] INTEGER OPTIONAL,
    Height [1] INTEGER OPTIONAL,
    Title  UTF8String
 }

如果您收到以下数据:

[1]INTEGER(750), UTF8String("A funny kitten")

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

You know that 750 is the Height and not the Width (there simply is no Width). Here you declare a new tag (in that case a context specific one) that serves two purposes: It tells the en-/decoder that this is an integer value (typing) and it tells it which integer value that is (naming).

但是隐式标记和显式标记之间有什么区别? 区别在于隐式标记只是命名数据,编码器/解码器需要知道该名称的类型/strong>,而显式标记名称并显式键入数据.

But what is the difference between implicit and explicit tagging? The difference is that implicit tagging just names the data, the en-/decoder needs to know the type implicitly for that name, while explicit tagging names and explicitly types the data.

如果标记是明确的,数据将被发送为:

If tagging is explicit, the data will be sent as:

[1]INTEGER(xxx), UTF8String(yyy)

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

so even if a decoder has no idea that [1] means Height, it knows that the bytes "xxx" are to be parsed/interpreted as an integer value. Another important advantage of explicit tagging is that the type can be changed in the future without changing the tag. E.g.

Length ::= [0] INTEGER

可以改为

Length ::= [0] CHOICE { 
    integer INTEGER,
    real    REAL 
}

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

Tag [0] still means length, but now length can either be an integer or a floating point value. Since the type is encoded explicitly, decoders will always know how to correctly decode the value and this change is thus forward and backward compatible (at least at decoder level, not necessarily backward compatible at application level).

如果标记是隐式的,数据将被发送为:

If tagging is implicit, the data will be sent as:

[1](xxx), UTF8String(yyy)

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

A decoder that doesn't know what [1] is, will not know the type of "xxx" and thus cannot parse/interpret that data correctly. Unlike JSON, values in ASN.1 are just bytes. So "xxx" may be one, two, three or maybe four bytes and how to decode those bytes depends on their data type, which is not provided in the data stream itself. Also changing the type of [1] will break existing decoders for sure.

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

Okay, but why would anyone use implicit tagging? Isn't it better to always use explicit tagging? With explicit tagging, the type must also be encoded in the data stream and this will require two additional bytes per tag. For data transmissions containing several thousand (maybe even millions of) tags and where maybe every single byte counts (very slow connection, tiny packets, high packet loss, very weak processing devices) and where both sides know all custom tags anyway, why wasting bandwidth, memory, storage and/or processing time for encoding, transmitting and decoding unnecessary type information?

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

Keep in mind that ASN.1 is a rather old standard and it was intended to achieve a highly compact representation of data at a time where network bandwidth was very expensive and processors several hundred times slower than today. If you look at all the XML and JSON data transfers of today, it seems ridiculous to even think about saving two bytes per tag.

这篇关于我需要一个例子来理解 ASN.1 中的隐式标记的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆