2010-07-21 13 views

risposta

2

Trovo che lo this thread sia abbastanza chiaro, contiene anche (piccoli) esempi anche se sono piuttosto degli esempi "estremi". Un esempio più "realistico" che utilizza i tag IMPLICIT può essere trovato in this page.

+1

per me come esempi per principianti non sono abbastanza chiari –

+0

mi sono perso negli esempi – achabahe

23

Nella codifica ASN.1, infatti, ha due scopi: digitare e denominare. Digitando significa che indica a un decodificatore quale tipo di dati è (è una stringa, un intero, un booleano, un set, ecc.), Il nome significa che se ci sono più campi dello stesso tipo e alcuni (o tutti) sono opzionali, indica all'en/decoder per quale campo quel valore è.

Se si confrontano ASN.1 a, diciamo, JSON, e si guardano i seguenti dati JSON:

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

noterete che in JSON ogni campo viene sempre chiamato in modo esplicito ("Immagine" , "Larghezza", "Altezza", "Titolo") e digitati in modo esplicito o implicito ("Titolo" è una stringa, poiché il suo valore è circondato da virgolette, "Larghezza" è un numero intero, perché non ha virgolette, solo cifre , non è "nullo", "vero" o "falso" e non ha periodo decimale).

In ASN.1 questo pezzo di dati sarebbe:

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

Ciò funzionerà senza alcuna etichettatura speciale, qui sono necessari solo i tag universali. Universal tags non nominare i dati, scrivono semplicemente i dati, quindi en/decoder sa che i primi due valori sono interi e l'ultimo è una stringa. Che il primo intero sia Larghezza e il secondo sia Altezza non ha bisogno di essere codificato nel flusso di byte, è definito dal loro ordine (le sequenze hanno un ordine fisso, gli insiemi no. in uso).

Ora modificare lo schema come segue:

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

Okay, ora abbiamo un problema. Supponiamo che vengano ricevuti i seguenti dati:

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

Che cos'è 750? Larghezza o altezza? Potrebbe essere Larghezza (e Altezza mancante) o potrebbe essere Altezza (e Larghezza manca), entrambi apparirebbero come un flusso binario. In JSON sarebbe chiaro come ogni dato sia denominato, in ASN.1 non lo è. Ora un tipo da solo non è sufficiente, ora abbiamo anche bisogno di un nome. È qui che i tag non universali entrano nel gioco. Modificarla in:

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

E se si ricevono i seguenti dati:

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

Tu sai che 750 è l'altezza e non il larghezza (semplicemente non c'è mm di larghezza). Qui si dichiara un nuovo tag (in questo caso uno specifico per il contesto) che ha due scopi: indica all'en/decoder che questo è un valore intero (digitando) e indica quale valore intero è (denominazione).

Ma qual è la differenza tra tagging implicito ed esplicito? La differenza è che il tag implicito non fa altro che denominare i dati, l'en-/decodificatore ha bisogno di conoscere il tipo implicitamente per tale nome, mentre i nomi di codifica esplicita e digita esplicitamente i dati.

Se il tagging è esplicito, i dati verranno inviati come:

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

quindi, anche se un decoder non ha idea che [1] significa altezza, si sa che i byte "XXX" devono essere analizzati/interpretato come un valore intero. Un altro importante vantaggio del tag esplicito è che il tipo può essere modificato in futuro senza modificare il tag. Per esempio.

Length ::= [0] INTEGER 

può essere cambiato in

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

Tag [0] ancora significa lunghezza, ma ora lunghezza può essere sia un numero intero o un valore in virgola mobile. Poiché il tipo è codificato in modo esplicito, i decodificatori sapranno sempre come decodificare correttamente il valore e questo cambiamento è quindi compatibile in avanti e indietro (almeno a livello di decodificatore, non necessariamente retrocompatibile a livello di applicazione).

Se la codifica è implicito, i dati saranno trasmessi come:

[1](xxx), UTF8String(yyy) 

Un decodificatore che non sa cosa [1] è, non conoscere il tipo di "xxx" e quindi non può analizzare/interpretare correttamente tali dati. A differenza di JSON, i valori in ASN.1 sono solo byte. Quindi "xxx" può essere uno, due, tre o forse quattro byte e come decodificare quei byte dipende dal loro tipo di dati, che non è fornito nel flusso di dati stesso. Anche la modifica del tipo di [1] interromperà sicuramente i decodificatori esistenti.

Ok, ma perché qualcuno dovrebbe usare il tagging implicito? Non è meglio usare sempre i tag espliciti? Con il tag esplicito, il tipo deve anche essere codificato nel flusso di dati e questo richiederà due byte aggiuntivi per tag. Per le trasmissioni di dati contenenti diverse migliaia (forse anche milioni di) tag e dove forse ogni singolo byte conta (connessione molto lenta, pacchetti minuscoli, perdita di pacchetti elevata, dispositivi di elaborazione molto deboli) e dove entrambe le parti conoscono comunque tutti i tag personalizzati, perché sprecare larghezza di banda , memoria, memoria e/o tempo di elaborazione per la codifica, la trasmissione e la decodifica di informazioni di tipo non necessarie?

Ricordare che ASN.1 è uno standard piuttosto vecchio ed era destinato a ottenere una rappresentazione estremamente compatta dei dati in un momento in cui la larghezza di banda della rete era molto costosa e i processori centinaia di volte più lenti di oggi. Se guardi tutti i trasferimenti di dati XML e JSON di oggi, sembra ridicolo persino pensare di salvare due byte per tag.

+0

Riferimento: https://osqa-ask.wireshark.org/questions/8277/difference-between-implicit-and-explicit -tag-ASN1. Qui, a) A :: = INTEGER con valore 5 è codificato come hex 02 01 05, b) B :: = [2] IMPLICIT INTEGER con valore 5 è codificato come esadecimale 82 01 05 ec) C :: = [2 ] EXPLICIT INTEGER con valore 5 è codificato come hex A2 03 02 01 05. Qualcuno potrebbe spiegare il caso b e il caso c! – AVA

+0

@AVA Se hai una domanda, perché non fai una domanda? Perché metti la tua domanda in un commento? QUINDI è tutto per fare domande, quindi prendilo e fai una domanda. – Mecki

Problemi correlati