2010-07-21 9 views

Antwort

2

Ich finde this thread um klar genug zu sein, es enthält auch (kleine) Beispiele, auch wenn sie ziemlich "extreme" Beispiele sind. Ein "realistischeres" Beispiel mit IMPLICIT-Tags finden Sie in this page.

+1

für mich als Anfänger Beispiele sind nicht klar genug –

+0

Ich bin in den Beispielen verloren – achabahe

23

In ASN.1 Tagging dient tatsächlich zwei Zwecken: Eingabe und Benennung. Eingeben bedeutet, dass es einem En-/Decoder mitteilt, welche Art von Datentyp das ist (ist es ein String, ein Integer, ein Boolean, ein Satz usw.), Benennung bedeutet, dass wenn mehrere Felder desselben Typs und einige (oder alle von ihnen sind optional, es teilt dem En-/Decoder mit, für welches Feld dieser Wert ist.

Wenn Sie ASN.1 vergleichen, um, sagen wir mal, JSON, und man sich die folgenden JSON-Daten:

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

Sie werden feststellen, dass explizit genannt („Bild“ in JSON bemerken wird jedes Feld immer "Breite", "Höhe", "Titel") und entweder explizit oder implizit eingegeben ("Titel" ist eine Zeichenkette, da ihr Wert von Anführungszeichen umgeben ist) "Breite" ist eine Ganzzahl, da sie keine Anführungszeichen, nur Ziffern enthält Es ist nicht "null", "wahr" oder "falsch", und es hat keine Dezimalstelle.

In ASN.1 dieses Stück Daten wäre:

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

Dies wird ohne besondere Kennzeichnung arbeiten, hier nur die allgemeinen Tags erforderlich sind. Universal tags Nennen Sie keine Daten, sie geben nur Daten ein, also wissen Sie, dass die ersten beiden Werte Ganzzahlen sind und die letzte eine Zeichenkette ist. Die erste Ganzzahl ist Width und die zweite ist Height muss nicht im Byte-Stream codiert werden, sie wird durch ihre Reihenfolge definiert (Sequenzen haben eine feste Reihenfolge, Mengen nicht. Auf der Seite, auf die Sie sich bezogen haben, sind Mengen verwendet werden).

nun das Schema wie folgt ändern:

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

Okay, jetzt haben wir ein Problem. Angenommen, die folgenden Daten werden empfangen:

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

Was ist 750? Breite oder Höhe? Könnte Breite sein (und Höhe fehlt) oder könnte Höhe sein (und Breite fehlt), beide würden gleich aussehen wie ein binärer Stream. In JSON wäre das klar, da jedes Datenelement benannt wird. In ASN.1 ist dies nicht der Fall. Jetzt reicht ein Typ alleine nicht, jetzt brauchen wir auch einen Namen. Hier kommen die nicht-universellen Tags ins Spiel. Ändern Sie ihn auf:

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

Und wenn Sie die folgenden Daten erhalten:

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

Sie wissen, dass 750 die Höhe und nicht die Breite (es gibt einfach keine Breite). Hier deklarieren Sie ein neues Tag (in diesem Fall ein kontextspezifisches), das zwei Zwecke erfüllt: Es teilt dem En-/Decoder mit, dass es sich um einen Integer-Wert (Typisierung) handelt und teilt ihm mit, welcher Integer-Wert (Benennung) ist.

Aber was ist der Unterschied zwischen implizitem und explizitem Tagging? Der Unterschied ist, dass das implizite Tagging nur die Daten benennt, der En-/Decoder muss den Typ implizit für diesen Namen kennen, während explizite Tagging-Namen und die Daten explizit eingibt.

Wenn Tagging explizit ist, werden die Daten als gesendet werden:

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

so dass selbst wenn ein Decoder keine Ahnung hat, dass [1] bedeutet, Höhe, weiß es, dass der Bytes „xxx“ wird analysiert werden/interpretiert als ganzzahliger Wert. Ein weiterer wichtiger Vorteil der expliziten Tagging ist, dass der Typ in der Zukunft geändert werden kann, ohne das Tag zu ändern. Z.B.

Length ::= [0] INTEGER 

kann

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

Tag [0] noch Länge bedeutet, geändert werden, aber nun entweder Länge eine ganze Zahl oder ein Gleitkommawert sein kann. Da der Typ explizit codiert ist, wissen Dekodierer immer, wie der Wert korrekt dekodiert wird, und diese Änderung ist somit vorwärts und rückwärts kompatibel (zumindest auf Dekodierebene, nicht notwendigerweise rückwärtskompatibel auf Anwendungsebene).

Wenn Tagging implizit ist, werden die Daten als gesendet werden:

[1](xxx), UTF8String(yyy) 

Ein Decoder, der nicht weiß, was [1] ist, wird nicht die Art von „xxx“ kennen und kann somit nicht analysieren/interpretiere diese Daten korrekt. Im Gegensatz zu JSON sind die Werte in ASN.1 nur Bytes. So kann "xxx" ein, zwei, drei oder vier Bytes sein und wie diese Bytes dekodiert werden, hängt von ihrem Datentyp ab, der nicht im Datenstrom selbst enthalten ist. Wenn Sie auch den Typ von [1] ändern, werden die vorhandenen Decoder sicher zerstört.

Okay, aber warum sollte jemand implizites Tagging verwenden? Ist es nicht besser, explizites Tagging zu verwenden? Beim expliziten Tagging muss der Typ auch im Datenstrom codiert werden, und dies erfordert zwei zusätzliche Bytes pro Tag. Für Datenübertragungen, die mehrere tausend (vielleicht sogar Millionen) Tags enthalten und wo möglicherweise jedes einzelne Byte zählt (sehr langsame Verbindung, winzige Pakete, hoher Paketverlust, sehr schwache Verarbeitungsgeräte) und wo beide Seiten sowieso alle benutzerdefinierten Tags kennen, warum Bandbreite verschwenden Speicher-, Speicher- und/oder Verarbeitungszeit zum Verschlüsseln, Übertragen und Decodieren unnötiger Informationen? Beachten Sie, dass ASN.1 ein ziemlich alter Standard ist und eine sehr kompakte Darstellung von Daten zu einer Zeit erreicht werden sollte, in der die Netzwerkbandbreite sehr teuer und die Prozessoren mehrere hundert Mal langsamer waren als heute. Wenn Sie sich alle XML- und JSON-Datenübertragungen von heute anschauen, erscheint es lächerlich, überhaupt daran zu denken, zwei Bytes pro Tag zu speichern.

+0

Referenz: https://osqa-ask.wireshark.org/questions/8277/difference-between-implicit-and-explicit -tags-asn1. Hier wird a) A :: = INTEGER mit dem Wert 5 als hex 02 01 05 codiert, b) B :: = [2] IMPLICIT INTEGER mit dem Wert 5 wird als hex 82 01 05 codiert und c) C :: = [2 ] EXPLICIT INTEGER mit Wert 5 ist als Hex A2 03 02 01 05 kodiert. Könnte jemand bitte Fall b und Fall c erklären! – AVA

+0

@AVA Wenn Sie eine Frage haben, warum stellen Sie nicht eine Frage? Warum stellst du deine Frage in einen Kommentar? Es geht darum, Fragen zu stellen, also gehen Sie darauf und stellen Sie eine Frage. – Mecki

Verwandte Themen