Basic Encoding Rules: differenze tra le versioni

Contenuto cancellato Contenuto aggiunto
mNessun oggetto della modifica
Errore nella condizione del campo length
Etichette: Modifica visuale Modifica da mobile Modifica da web per mobile
 
(68 versioni intermedie di 33 utenti non mostrate)
Riga 1:
{{W|informatica|ottobre 2023}}
{{W|informatica|luglio 2007|[[Utente:LaseriumFloyd|LaseriumFloyd]] 10:55, 29 lug 2007 (CEST)}}
'''Basic Encoding Rules''' (abbreviazione '''BER''') è un sistema di codifica composto da una serie di regole per la conversione di dati eterogenei in flussi di [[byte|bytes]].
 
'''Basic Encoding Rules''' (abbreviazione '''BER''') è un sistema di [[Codice (teoria dell'informazione)|codifica]] composto da una serie di regole per la conversione di dati eterogenei in flussi di [[byte]].
La codifica BER è strettamente legata allo standard [[ASN.1]] ed è utilizzata per le comunicazioni [[SNMP]] e [[LDAP]].
 
La codifica BER è strettamente legata allo standard [[ASN.1]] ed è utilizzata per le comunicazioni [[Simple Network Management Protocol|SNMP]] e [[Lightweight Directory Access Protocol|LDAP]].
 
== Sistema di codifica ==
Il sistema di codifica è basato sul concetto di tripla <T,L,V> (Type o Tag, Length, Value) dove:
*''Type'' o ''Tag'' : indica il tipo del dato codificato
*''Length'' : indica la lunghezza in byte di "Value"
*''Value'' : È il dato codificato vero e proprio
 
 
Quindi ad esempio per codificare il dato 7 come INTERO occorreranno 3 bytes:
*il primo che indica il ''Type'' (<math>INTERO = 02_16</math>02₁₆);
*il terzosecondo èche indica la codifica''Length'' deldi dato INTERO secondo le regole BERv (in questo caso <math>07_16</math>= 01₁₆);.
*il secondoterzo che indicaè la ''Length''codifica didel vdato INTERO secondo le regole BER (in questo caso = <math>01_16</math>07₁₆).;
 
In definitiva INTEGER 7 in BER diviene <math>020107_16</math>020107₁₆ dove si distinguono chiaramente T,L e V.
 
== BER e ASN.1 ==
 
=== BER e ASN.1 ===
BER è strettamente legata ad ASN.1 soprattutto per quanto riguarda i tipi di dati.
Come si puo'può immaginare la codifica di V dipende dal tipo T.
Ci sono alcuni tipi predefiniti in ASN.1 (si dice che sono ''Tag appartenenti alla Class UNIVERSAL'').
Per maggiori infoinformazioni a tal proposito consultare [httphttps://wwwweb.ossarchive.comorg/asn1web/20081205052919/booksintro.html] o [http://www.oss.com/asn1/booksintro.html OSS Nokalva - Books Overview].
 
 
== Codifica BER ==
In generale quando si deve effettuare la codifica BER di un dato si procede nenel seguente modo:
#si codifica T;
#si codifica V;
Riga 32 ⟶ 31:
 
Vediamo ora la codifica di ogni campo.
 
 
=== Codifica di T ===
La codifica del campo T di solito chiede un unico Byte. La codifica dipende dai seguenti fattori:
*La classe di appartenenza del ''Tag''
*Il tipo è ''PRIMITIVE'' o ''CONSTRUCTED''
*L'identificativo del ''Tag'' nella classe di appartenenza
 
Se l'identificativo del tipo <math>0<=ID<=30</math> allora la codifica di ''T'' richiede un unico byte, altrimenti il numero di byte di ''T'' dipenderà dal valore di ''ID''
 
==== Primo byte di T ====
Vediamo qui sotto come si presenta il primo byte di ''T'':
[[immagineFile:BERPrimobyte_TBERPrimobyte T.JPG |thumb|center|Primo byte di T]]
 
La codifica di ''CLASS'' segue la seguente tabella:
Riga 55 ⟶ 53:
1 1 PRIVATE
 
Il bit ''P\C'' = 0 indica che il tipo è ''PRIMITIVE'' (cioè è un tipo semplice come INTEGER o OID)
 
Il bit ''P\C'' = 01 indica che il tipo è PRIMITIVE''CONSTRUCTED'' (cioè è un tipo semplicecomposto da più tipi semplici come INTEGERad oes. OIDSEQUENCE)
 
I 5 bit di ''TAG'' invece:
Il bit P\C = 1 indica che il tipo è CONSTRUCTED (cioè è un tipo composto da più tipi semplici come ad es. SEQUENCE)
*Contengono il valore binario di ''ID'' se <math>0<=ID<=30</math>
*Contengono <math>11111_2</math> se <math>ID>30</math>
 
Nel primo caso, come è stato già detto, il ''T'' è composto da un unico byte.
Nel secondo caso vanno invece codificati gli altri bytes di ''T''.
 
I==== 5Altri byte di TAGT invece:====
Per codificare gli altri byte si procede nel seguente modo:
*Contengono il valore binario di ID se <math>0<=ID<=30</math>
#si converte l{{'}}''ID'' in binario
*Contengono <math>11111</math> se <math>ID>30</math>
 
Nel primo caso, come è stato già detto, il T è composto da un unico byte.
Nel secondo caso vanno invece codificati gli altri bytes di T.
 
==== Altri bytes di T ====
Per codificare gli altri bytes si procede nel seguente modo:
#si converte l' ''ID'' in binario
#si aggiunge un '''1''' ogni 7 bit
#si completa il byte con un 10 in testa
 
NB !!! appena corretto!!! l'ultimo byte che compone l'ID viene composto con uno '0' in testa, proprio per indicare che l'ID finisce con quel byte.
[[immagine:Altribytes_T.JPG |thumb|500px|center|Altri bytes di T]]
 
[[File:Altribytes T.JPG|thumb|upright=2.3|center|Altri bytes di T]]
 
Ad es. se ID = 250 in base 10, allora:
#<math>250_10250_{10} = FA_16FA_{16} = 11111010_2</math>
#<math>11111010 -> 1 '''\textbf{1'''}1111010</math>
#<math>1 '''\textbf{1'''}1111010 -> '''\textbf{1'''}0000001 '''1'''~\textbf{0}1111010</math>
 
In definitiva ID = 250 viene codificato con 0x81FA
 
In definitiva ID = 250 viene codificato con <math>81FA_{16}</math>
 
==== Esempio 1 di codifica di T ====
Codifica di INTEGER. Questo è di classe UNIVERSAL ed è PRIMITIVE.
Il suo ID nella classe UNIVERSAL è 2.
:<math>ID<=30</math> e quindi basterà 1 solo byte per T
 
Quindi:
:''CLASS'' = 00
:''P\C'' = 0
:''Tag'' = 00010
 
da cui se segue:
:<math>T = 02_{16}</math>
T = 0x02
 
 
==== Esempio 2 di codifica di T ====
Supponiamo di voler codificare un tipo PRIVATE e PRIMITIVEconPRIMITIVE con <math>ID = 250250_{10}</math>
:<math>ID>30</math> e quindi serviranno più bytesbyte per T
 
Primo byte:
:''CLASS'' = 11
:''P\C'' = 0
:''Tag'' = 11111 --> <math>primobyte = 0b1101111111011111_2 = 0xDFDF_{16}</math>
 
Altri byte (come abbiamo visto in precedenza) sono pari a 0x81FA<math>81FA_{16}</math> perché <math>ID = 250250_{10}</math>
 
 
In definitiva in questo caso T = 0xDF81FA ed è di 3 bytes
 
In definitiva in questo caso <math>T = DF81FA_{16}</math> ed è di 3 [[byte]].
 
=== Codifica di L ===
In questa sezione si indica con ''Len(V)'' il numero di bytesbyte di ''V''. </br>
 
La codifica di L è strettamente legata alla lunghezza del dato codificato ''V''.
Se si conosce a priori ''Len(V)'' allora si procede con la codifica ''definite length'', altrimentealtrimenti si applica la codifica ''indefinite length''. La prima tecnica è preferibile in quanto permette un Decoding più semplice.
 
==== Encoding di L 'definite length' ====
In questo tipo di encoding si distinguono 2 casi distinti:
#se <math>Len(V)<=127</math> allora ''L'' viene codificato in 1 byte (''short definite form'')
#se <math>Len(V)>127</math> allora ''L'' viene codificato in più byte (''long definite form'')
 
===== Caso 1: ''L'' in 1 byte - ''short definite form'' =====
Questo è il caso più semplice. ''V'' è codificato in meno di 127 bytes ed L contiene esclusivamente il valore di ''Len(V)'' in esadecimale </br> .
 
Il limite di 127 bytes è dato dal fatto che 127 è 0x7F in esadecimale (01111111 in binario) e quindi il primo bit di ''L'' è sicuramente zero.
Il limite di 127 byte è dato dal fatto che 127 è 7F in esadecimale (01111111 in binario) e quindi il primo bit di ''L'' è sicuramente zero.
Ciò è utile in fase di Decoding, infatti se il primo bit è zero, significa che è stata usata la codifica di L su un solo byte.
 
[[immagine:Short_Defined_Form_L.JPG |thumb|center|L in Short Defined Form]]</br>
Ciò è utile in fase di Decoding, infatti se il primo bit è zero, significa che è stata usata la codifica di L su un solo byte.
===== Caso 2: ''L'' in più bytes ''long definite form'' =====
[[File:Short Defined Form L.JPG|thumb|center|L in Short Defined Form]]
 
===== Caso 2: ''L'' in più bytes - ''long definite form'' =====
In questo caso si procede nel seguente modo:
#si codifica in binario ''Len(V)''
#si calcola <math>Len(Len(V)) \,\!</math>, cioè la lunghezza in bytes di ''Len(V)''
#si pone nel primo byte di ''L'' = <math>Len(Len(V))+ 0x80\,\!80_{16}</math>
#si pone nei bytes seguenti ''Len(V)''
 
La formula del punto 3 ha la seguente giustificazione:
*aggiungendo 0x80<math>80_{16}</math> si obbliga l'ultimo bit del primo byte di L ad essere 1.
*nei primi 7 bitsbit del primo byte di ''L'' c'è in realtà la lunghezza dei bytesbyte restanti di ''L'', infatti <math>Len(Len(V))+1</math> indica proprio la lunghezza di L </br>
[[immagineFile:Long_Defined_Form_LLong Defined Form L.JPG |thumb|650pxupright=3|center|L in Long Defined Form]]</br>
In fase di Decoding per capire che stiamo usando una codifica di L su più bytesbyte di tipo ''long definite form'' deve quindi essere:
*il primo bit del primo byte di ''L''= 1
*gli altri 7 bit del primo byte devono essere diversi da <math>\ne 0b00000000000000_2</math>
 
===== Esempio 1 di Codifica di L in ''definite form'' =====
''V'' è codificato su 120 bytes.</br> Poiché <math>120<127</math> deve essere quindi usata la ''short definite form''</br>In definitiva:<math>L = 0x78</math>
===== Esempio 2 di Codifica di L in ''definite form'' =====
''V'' è codificato su 1000 bytes.</br> Poiché <math>1000>127</math> deve essere quindi usata la ''long definite form''</br>Quindi:
#<math>Len(V)= 1000_{10} = 0x3E8 = 0x03E8</math>
#<math>Len(Len(V)) = 2_{10} = 0x02</math>
#''byte 1 di L '' <math>= Len(Len(V)) + 0x80 = 0x82 = 10000010_2</math>
#''bytes 2,3 di L '' <math>= Len(V) = 0x03E8</math></br>
In definitiva:<math>L = 0x8203E8</math> ed è di <math>Len(Len(V)) + 1 = 2 + 1 = 3 bytes</math>
 
Poiché <math>120<127</math> deve essere quindi usata la ''short definite form''
:In definitiva:<math>L = 78_{16}</math>
 
===== Esempio 2 di Codifica di L in ''definite form'' =====
''V'' è codificato su 1000 bytes.
 
Poiché <math>1000_{10}>127_{10}</math> deve essere quindi usata la ''long definite form''.
 
Quindi:
#<math>Len(V)= 1000_{10} = 3E8_{16} = 03E8_{16}</math>
#<math>Len(Len(V)) = 2_{10} = 02_{16}</math>
#''byte 1 di L '' <math>= Len(Len(V)) + 80_{16} = 82_{16} = 10000010_2</math>
#''bytes 2,3 di L '' <math>= Len(V) = 03E8_{16}</math>
In definitiva:<math>L = 8203E8_{16}</math> ed è di <math>Len(Len(V)) + 1 = 2 + 1 = 3 bytes</math>
 
==== Encoding 'indefinite length' ====
Riga 158 ⟶ 163:
 
In questo caso si procede con i seguenti passi:
*si pone <math>L=10000000_2 = 0x8080_{16}</math>
*si aggiunge ''V''
*in coda a ''V'' si aggiungono 2 bytes di zeri 0x0000<math>0000_{16}</math>
 
 
 
=== Codifica di V ===
La codifica di ''V'', come è stato più volte detto, dipende taldal tipo ''T'' e dalla sua definizione tramite sintassi [[ASN.1]] In questa sede sara'sarà illustrata la codifica dei 3 tipi principali: INTEGER, OCTECT STRING e OBJECT ID. Per una panoramica completa di codifica decodifica si rimanda ancora a [https://web.archive.org/web/20081205052919/http://www.oss.com/asn1/booksintro.html OSS Nokalva - Books Overview] o [https://web.archive.org/web/20081205052919/http://www.oss.com/asn1/booksintro.html] </br>OSS Nokalva - Books Overview]
 
 
==== Codifica di ''INTEGER'' ====
La codifica di un dato INTEGER dipende dal suo segno. Il primo bit del primo byte codificato è detto ''bit segno''. Se questo è 0 allora il numero è positivo, altrimenti è negativo. </br>
 
===== INTEGER Positivi =====
In questo caso la codifica è data dal valore binario del numero, a patto che si rispetti il ''bit segno'', altrimenti bisogna aggiungere in testa un byte di zeri</br>
 
Infatti se l'integer è ad es. 100<math>100_{10}</math> allora si ha: <math>valore =100100_{10} \to V = 100_{10} = 0x6464_{16} = 01100100_2</math>. In questo caso il ''bit segno'' è zero e quindi la codifica è corretta.</br>
 
Se invece l'integer è ad es. 250 allora si ha: <math>V = 250_{10} = 0xFAFA_{16} = 11111010_2</math>. In questo caso il ''bit segno'' è 1 e quindi in fase di decodifica rappresenterebbe un numero negativo, vanno quindi aggiunti gli zeri in testa. In definitiva <math>valore =250 \to V = 250_{10} = 0xFAFA_{16} = 0x00FA00FA_{16} = 0000000011111010_2</math>. Come si puo'può notare, aggiungendo gli zeri in testa il ''bit segno'' è correttamente zero.
 
===== INTEGER Negativi =====
Per gli integer negativi si utlizzautilizza il [[Complemento_a_due|''[[Complemento a due'']]'' del valore. Ciò assicura che il ''bit segno'' è sempre negativo.
In particolare i passi da seguire sono:
* si codifica <math>\left |valore \right |</math> con le regole indicate sopra
* si calcola il ''Complemento a uno'' cioè si nega bit a bit
* si aggiunge infine al numero ottenuto <math>+ 1_2</math> </br>
 
 
Ad esempio se valore = -100 si ha:
* <math>\left |valore \right | =\left |-100 \right | = 100_{10} = 01100100_2</math> <small>(vedi es. INTEGER Positivi)</small>
* complemento a 1: <math>01100100_2 -> 10011011_2</math>
* aggiungere <math>+ 1_2</math>. Si ottineottiene <math>10011011_2 + 1_2 = 10011100_2</math></br>
Quindi <math>valore = -100 \to V = 10011100_2 = 0x9C9C_{16} \,\!</math></br></br>
 
 
Se invece valore = -250 si ha:
* <math>\left |valore \right | = \left |-250 \right | = 250_{10} = 0000000011111010_2</math> <small>(vedi es. INTEGER Positivi)</small>
* complemento a 1: <math>0000000011111010_2 -> 1111111100000101_2</math>
* aggiungere <math>+ 1_2</math>. Si ottine <math>1111111100000101_2 + 1_2 = 1111111100000110_2</math></br>
Quindi <math>valore = -250 \to V = 1111111100000110_2 = 0xFF06\,\!FF06_{16}</math></br></br>
 
==== Codifica di ''OCTECT STRING'' ====
In ASN.1 sono definite una grande varietà di stringhe, ma l'OCTECT STRING è quella fondamentale. In questo caso ogni carattere occupa 1 byte e viene utilizzata la codifica [[ASCII]]. </br>
 
Ad esempio l' OCTECT STRING "ciao" viene codificato in 4 bytes in 0x6369616F
Ad esempio l'OCTECT STRING "ciao" viene codificato in 4 byte in <math>6369616F_{16}</math>
 
==== Codifica di ''OBJECT IDENTIFIER'' ====
Un OBJECT IDENTIFIER (abbreviato è OID) è un identificatore univoco di un campo della [[Management Information Base|MIB]].
 
Un OID è formato da ''n'' numeri divisi da ''n-1'' punti. Un esempio di OID è il seguente: 1.2.250.1.16.9
 
I passi per codificare un OID sono i seguenti:
#si pone nel primo [[byte]] il valore <math>40*primonumero + secondonumero</math>
#si codificano gli altri numeri in [[byte]] separati con le seguenti regole:
##se <math>numero <= 127 </math> si usa semplicemente la rappresentazione binaria di ''numero''
##se <math>numero > 127 </math> si usa la rappresentazione binaria di ''numero'' con:
###uno '''0''' inframezzato ad ogni 7 bit
###un '''1''' come primo bit del primo [[byte]]
 
Ad esempio codifica di 1.2.250.1.16.9:
*<math>primobyte = 40 * 1 + 2 = 42_{10} = 2A_{16}</math>
*<math>250_{10} = FA_{16} = 11111010_2</math> -> '''1'''000 0001 | '''0'''111 1010 -> 1000 0001 0111 1010 = <math>817A_{16}</math>
*<math>1_{10} = 01_{16}</math>
*<math>16_{10} = 10_{16}</math>
*<math>9_{10} = 09_{16}</math>
Quindi 1.2.250.1.16.9 -> 2A 817A 01 10 09 = <math>2A817A011009_{16}</math>
 
== Voci correlate ==
* [[Simple Network Management Protocol]]
* [[Lightweight Directory Access Protocol]]
 
== Altri progetti ==
{{interprogetto}}
 
== Collegamenti esterni ==
#* {{en}} [https://web.archive.org/web/20081205052919/http://www.oss.com/asn1/booksintro.html Olivier Dubuisson - ASN.1: Communication Between Heterogeneous Systems] - Free PDF book
#* {{en}} [https://web.archive.org/web/20081205052919/http://www.oss.com/asn1/booksintro.html Professor John Larmouth - ASN.1 Complete] - Free PDF book
 
{{Portale|Informatica}}
 
[[Categoria:Codifica]]
[[en:Basic Encoding Rules]]
[[es:BER]]
[[fr:Basic encoding rules]]
[[pl:Basic Encoding Rules]]