2010-07-21 61 views

回答

2

我發現this thread已經足夠清楚了,它還包含(小)例子,即使很難,它們也是非常「極端」的例子。在this page中可以找到使用IMPLICIT標籤的更實際的示例。

+1

我作爲初學者的例子不夠清晰 – 2012-05-29 16:17:15

+0

我已經在實施例中已經失去了 – achabahe 2017-06-18 21:21:52

23

在ASN.1標記中,實際上它有兩個目的:打字和命名。打字意味着它告訴en /解碼器是什麼類型的數據類型(它是一個字符串,一個整數,一個布爾值,一組等等),命名意味着如果有多個相同類型的字段和一些或者全部)是可選的,它告訴en /解碼器哪個字段的值是。

如果你比較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?寬度還是高度?可能是寬度(並且缺少高度)或者可能是高度(並且缺少寬度),它們看起來與二進制流相同。在JSON中,每個數據都被命名,這在ASN.1中就不是了。現在只有一種類型是不夠的,現在我們還需要一個名稱。這就是非通用標籤進入遊戲的地方。將其更改爲:

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

如果你收到了如下數據:

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

你知道750是高度而不是寬度(目前根本沒有寬度)。在這裏你聲明瞭一個新的標籤(在這種情況下是一個特定的上下文),它有兩個目的:它告訴en /解碼器這是一個整型值(輸入),它告訴它哪個(命名)的整數值。

但隱式標籤和顯式標籤有什麼區別?區別在於隱式標記只是命名數據,en- /解碼器需要隱式知道該名稱的類型,而顯式標記名稱和明確地鍵入數據

如果標記是顯式的,則數據將被髮送爲:

[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數據傳輸,甚至考慮爲每個標籤保存兩個字節,這似乎很荒謬。

+0

參考:https://osqa-ask.wireshark.org/questions/8277/difference-between-implicit-and-explicit標籤都有效,ASN1。這裏,a)值爲5的A :: = INTEGER編碼爲十六進制02 01 05,b)B :: = [2]值爲5的IMPLICIT INTEGER編碼爲十六進制數82 01 05,c)C :: = [2 ]值爲5的EXPLICIT INTEGER編碼爲十六進制A2 03 02 01 05.任何人都可以解釋案例b和案例c! – AVA 2018-02-28 09:42:36

+0

@AVA如果你有問題,你爲什麼不問一個問題?你爲什麼要把你的問題置於評論中?所有這些都是關於提問的,所以去找它並提出一個問題。 – Mecki 2018-02-28 11:24:47