2010-07-21 14 views

Odpowiedz

2

Uważam, że this thread jest wystarczająco przejrzysty, zawiera także (małe) przykłady, nawet jeśli są dość "ekstremalnymi" przykładami. Bardziej "realistyczne" przykłady z użyciem znaczników IMPLICIT można znaleźć w this page.

+1

dla mnie jako przykłady dla początkujących nie są wystarczająco jasne –

+0

Zgubiłem się w przykładach – achabahe

23

W tagowaniu ASN.1 w rzeczywistości służy dwóm celom: pisaniu na klawiaturze i nazywaniu. Wpisanie oznacza, że ​​informuje en-/dekoder, jakiego rodzaju jest dany typ danych (czy jest to ciąg, liczba całkowita, boolean, zestaw itd.), Nazewnictwo oznacza, że ​​jeśli istnieje wiele pól tego samego typu i kilka (lub wszystkie z nich) są opcjonalne, informuje en/dekoder, dla którego pola jest ta wartość.

Jeśli porównać ASN.1 do, powiedzmy, JSON, i spojrzeć na następujące dane JSON:

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

Zauważysz, że w JSON każde pole jest zawsze wyraźnie nazwie („Obraz” , "Szerokość", "Wysokość", "Tytuł") i jawnie lub niejawnie wpisane ("Tytuł" jest łańcuchem, ponieważ jego wartość jest otoczona cudzysłowami, "Szerokość" jest liczbą całkowitą, ponieważ nie ma cudzysłowów, tylko cyfry nie ma wartości "null", "true" ani "false" i nie ma okresu dziesiętnego).

W ASN.1 ten element danych może być:

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

to będzie działać bez specjalnego znakowania, tu wymagane są tylko uniwersalne tagi. Universal tags nie wymieniaj danych, po prostu wpisują dane, więc en-/dekoder wie, że pierwsze dwie wartości są liczbami całkowitymi, a ostatnia jest ciągiem. Że pierwsza liczba całkowita to Szerokość, a druga to Wysokość nie musi być zakodowana w strumieniu bajtów, jest zdefiniowana przez ich kolejność (sekwencje mają ustaloną kolejność, zestawy nie. w użyciu).

teraz zmienić schemat następująco:

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

Dobra, teraz mamy problem. Załóżmy, że otrzymano następujące dane:

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

Co to jest 750? Szerokość lub wysokość? Może być Szerokość (i wysokość brakuje) lub może być Wysokość (i szerokość), oba wyglądają tak samo jak strumień binarny. W JSON, które byłoby jasne, jak każdy element danych jest nazwany, w ASN.1 nie jest. Teraz sam typ nie wystarczy, teraz potrzebujemy też nazwy. Tam wkraczają nie-uniwersalne tagi. Zmień go na adres:

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

A jeśli otrzymują następujące dane:

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

Wiesz, że 750 jest wysokość, a nie Szerokość (po prostu nie ma szerokość). Tutaj deklarujesz nowy znacznik (w tym przypadku specyficzny dla kontekstu), który służy dwóm celom: Mówi en-/dekoderowi, że jest to wartość całkowita (pisanie) i informuje ją, która wartość całkowita jest (nazywanie).

Jaka jest różnica między tagami niejawnymi a jawnymi? Różnica polega na tym, że niejawne tagowanie tylko nadaje nazwy, en/dekoder musi znać typ pośrednio dla tej nazwy, podczas gdy jawne nazwy znaczników i jawnie wpisują dane.

Jeśli tagowanie jest jawne dane zostaną wysłane jako:

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

więc nawet jeśli dekoder nie ma pojęcia, że ​​[1] oznacza wysokość, to wie, że bajty „XXX” mają być przetwarzane/interpretowane jako wartość całkowita. Inną ważną zaletą jawnego tagowania jest to, że typ można zmienić w przyszłości bez zmiany tagu. Na przykład.

Length ::= [0] INTEGER 

można zmienić

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

Tag [0] Jeszcze oznacza długość, ale teraz długość może być albo liczbą całkowitą lub zmiennoprzecinkową. Ponieważ typ jest jawnie zakodowany, dekodery zawsze będą wiedzieć, jak poprawnie dekodować wartość, a ta zmiana jest zgodna w przód i wstecz (przynajmniej na poziomie dekodera, niekoniecznie zgodna wstecz na poziomie aplikacji).

Jeśli tagowanie jest niejawne, dane będą wysyłane jako:

[1](xxx), UTF8String(yyy) 

dekodera, który nie wie, co [1], nie będzie wiedział, typ „XXX”, a zatem nie można analizować/poprawnie interpretować te dane. W przeciwieństwie do JSON, wartości w ASN.1 są po prostu bajtami. Zatem "xxx" może być jednym, dwoma, trzema lub nawet czterema bajtami i sposób dekodowania tych bajtów zależy od ich typu danych, który nie jest dostarczany w samym strumieniu danych. Zmiana typu [1] na pewno zepsuje istniejące dekodery.

OK, ale dlaczego ktoś miałby używać niejawnego tagowania? Czy nie lepiej zawsze używać jawnego tagowania? W przypadku jawnego tagowania typ musi być również zakodowany w strumieniu danych, co będzie wymagać dwóch dodatkowych bajtów na znacznik. Do transmisji danych zawierających kilka tysięcy (może nawet milionów) znaczników i gdzie może być każdy bajt (bardzo wolne połączenie, małe pakiety, duża utrata pakietów, bardzo słabe urządzenia przetwarzające) i gdzie obie strony znają wszystkie niestandardowe znaczniki, dlaczego marnują przepustowość , pamięć, pamięć i/lub czas przetwarzania na kodowanie, przesyłanie i dekodowanie niepotrzebnych informacji o typie?

Należy pamiętać, że ASN.1 jest raczej starym standardem i miał na celu uzyskanie bardzo zwartej reprezentacji danych w czasie, gdy przepustowość sieci była bardzo droga, a procesory kilkaset razy wolniejsze niż obecnie. Jeśli spojrzeć na dzisiejsze transfery danych XML i JSON, wydaje się niedorzeczne nawet myślenie o zapisaniu dwóch bajtów na znacznik.

+0

Odsyłacz: https://osqa-ask.wireshark.org/questions/8277/difference-between-implicit-and-exicit -tags-asn1. Tutaj, a) A :: = INTEGER o wartości 5 jest zakodowany jako szesnastkowy 02 01 05, b) B :: = [2] IMPLICIT INTEGER o wartości 5 jest zakodowany jako heks 82 01 05 i c) C :: = [2 ] DOWIEDZ SIĘ INTEGER z wartością 5 jest zakodowany jako szesnastkowy A2 03 02 01 05. Czy ktokolwiek mógłby wyjaśnić przypadek b i przypadek c! – AVA

+0

@AVA Jeśli masz pytanie, dlaczego nie zadasz pytania? Dlaczego umieszczasz pytanie w komentarzu? W SO chodzi o zadawanie pytań, więc idź do niego i zadaj pytanie. – Mecki

Powiązane problemy