簡體   English   中英

ASN.1 序列混淆

[英]ASN.1 Sequence Confusion

我正在研究ASN.1的語法,並且在網上閱讀了很多相關材料:

http://www.itu.int/rec/T-REC-X.690-200811-I/en
http://luca.ntop.org/Teaching/Appunti/asn1.html
http://www.obj-sys.com/asn1tutorial/node11.html

我對 ASN.1 SEQUENCE類型的編碼感到非常困惑。 一般而言,我意識到SEQUENCE基本上是一個聚合體——在大多數編程語言中我們稱之為 OBJECT 或 INSTANCE。 它基本上是一個名稱/值對列表,類似於 JSON 對象。 但與 JSON 對象不同,ASN.1 SEQUENCE具有隱式 SCHEMA,因為它是“類”實例

因此, SEQUENCE的類/模式可能類似於:

{
  name  UTF8String
  age   INTEGER
}

該模式的一個實例可能是SEQUENCE

{
  "John Smith"
  42
}

但是我對如何在實際 BER 編碼中區分 CLASS 和 INSTANCE 之間的區別感到非常困惑。 事實上,我很困惑,我什至不確定 ASN.1 SEQUENCE應該是類定義還是類的實例。

文檔似乎暗示它是一個實例:

8.9序列值的編碼

8.9.1應構造序列值的編碼。

8.9.2內容八位字節應由序列類型的 ASN.1 定義中列出的每個類型的一個數據值的完整編碼組成,按照它們在定義中出現的順序,除非類型被引用關鍵字 OPTIONAL 或關鍵字 DEFAULT。

8.9.3對於用關鍵字 OPTIONAL 或關鍵字 DEFAULT 引用的類型,數據值的編碼可以,但不是必須的。 如果存在,它應出現在編碼中對應於 ASN.1 定義中類型出現的點。

所以看起來 SEQUENCE 只是一個數據值列表,它必須對應於某個模式(類)。 但是 ASN.1 沒有CLASS類型,那么您如何獲得實際的類,以便您知道任何給定的 SEQUENCE 是哪個類的實例?

假設你寫了以下內容:

R DEFINITIONS AUTOMATIC TAGS ::=

 BEGIN

 USPostalAddress ::= SEQUENCE {

      street     IA5String,

      city       IA5String,

      state      IA5String (SIZE (2)) (FROM("A".."Z")),

      zipcode    IA5String (SIZE (5)) (FROM("0".."9"))

 }

 END

上面 BEGIN 和 END 之間的部分稱為“類型分配”。 “USPostalAddress”是(用戶定義的)“類型”的名稱。 通過編寫上述內容,您已經指定了一個用戶定義的類型並為其命名。 每個 SEQUENCE 構造(例如上面的 SEQUENCE 構造)都是一個“類型”。 它是一種復雜類型,因為它包含一個或多個“字段”,每個“字段”都有自己的類型。 上述類型的可能“值”表示如下:

{ street "1234 Main St.", city "New York", state "NY", zipcode "12345" }

我們只是在談論類型和它們的值,而不是類和實例。 就像您可以擁有一個類型為 INTEGER (0..15) 的值是 0 到 15 之間的整數一樣,您可以擁有一個 SEQUENCE 類型,其值是較低級別值的排列。 上述序列類型是您可以在 ASN.1 中定義的數據結構(“類型”)的一個非常簡單的示例。

(在 ASN.1 中還有一個叫做“類”的東西,但它是完全不同的東西。)

在 ASN.1 中,協議的消息通常被指定為頂級類型(通常是 SEQUENCE 或 CHOICE 類型)。 特定的“消息值”是頂級類型的值。 當您擁有頂級類型的值時,您可以使用標准編碼規則之一(BER、PER 等)將該值編碼為位流。 當您從網絡接收到一個比特流時,您知道它是一個特定 ASN.1 類型的值,以 BER、PER 等編碼,您可以對這些比特進行解碼並獲得原始值。

ASN.1 文件通常包含這樣的序列類型的類型分配(類型定義):

myMessage ::= SEQUENCE
{
    a INTEGER(0..100),
    b INTEGER
}

ASN.1 文件中的那些 SEQUENCE 類型可以被認為與 C++/java 中的類或 C 中的結構定義相同。

SEQUENCE 的實例可以是程序中的編碼格式(BER、PER、DER 等)或本地格式(對象/變量)。

示例如何在 C 代碼中實現這些:

struct myMessage_t          
{
  int a;
  int b;
};

char buffer[1000];   // BER encoded instance will be stored to this buffer
myMessage_t msg;     // this is the local instance

msg.a = 1;
msg.b = 2;

size_t berLen = berEncode_myMessage( &msg, buffer, sizeof(buffer) );

和解碼方面:

myMessage_t msg2;            
berDecode_myMessage( buffer, berLen, &msg2 );
assert( msg2.a == 1 );

在解碼之前,您通常知道什么是編碼實例的頂級類型。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM