Basic Encoding Rules: differenze tra le versioni

Contenuto cancellato Contenuto aggiunto
Nessun oggetto della modifica
Errore nella condizione del campo length
Etichette: Modifica visuale Modifica da mobile Modifica da web per mobile
 
(94 versioni intermedie di 36 utenti non mostrate)
Riga 1:
{{SW|informatica|ottobre 2023}}
== Introduzione ==
'''Basic Encoding Rules''', abbreviata '''BER''' è una codifica rappresentante 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 è associata 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'' : E'È il dato codificato vero e proprio
 
 
Quindi ad esempio per codificare il dato 7 come INTERO occorreranno 3 bytes:
*il primo che indica il tipo''Type'' (INTERO = 0x0202₁₆);
*il secondo che indica la lunghezza''Length'' di v (in questo caso = 0x0101₁₆).
*il terzo è la codifica di undel dato interoINTERO secondo le regole BER (in questo caso 0x0707₁₆);
 
In definitiva INTEGER 7 in BER diviene 0x020107 dove si distinguono chiaramente T,L e V
 
In definitiva INTEGER 7 in BER diviene 020107₁₆ dove si distinguono chiaramente T,L e V.
 
=== 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;
#dalla lunghezza di V si passa alla codifica di L.
 
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:
*laLa classe di appartenenza del ''Tag''
*ilIl tipo è ''PRIMITIVE'' o ''CONSTRUCTED''
*lL'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:
 
bit 7 bit 6 CLASS
Line 56 ⟶ 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 = 0 indica 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 11111 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 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:
#250 = 0xFA = 11111010
#11111010 -> 1 '''1'''1111010
#1 '''1'''1111010 -> '''1'''0000001 '''1'''1111010
 
InAd definitivaes. se ID = 250 vienein codificatobase con10, 0x81FAallora:
#<math>250_{10} = FA_{16} = 11111010_2</math>
#<math>11111010 -> 1 \textbf{1}1111010</math>
#<math>1\textbf{1}1111010 -> \textbf{1}0000001~\textbf{0}1111010</math>
 
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èperché <math>ID = 250250_{10}</math>
 
In definitiva in questo caso <math>T = DF81FA_{16}</math> ed è di 3 [[byte]].
 
In definitiva in questo caso T = 0xDF81FA ed è di 3 bytes
 
=== 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.
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', altrimente si applica la codifica 'indefinite length'. La prima tecnica è preferibile in quanto permette un Decoding più semplice.
Se si conosce a priori ''Len(V)'' allora si procede con la codifica ''definite length'', altrimenti 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.
 
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.
===== Caso 1: L in 1 byte =====
Questo è il caso più semplice. V è codificato in meno di 127 bytes ed L contiene esclusivamente il valore di 'Len(V)' </br>
Quindi se ad esempio V è codificato su 120 bytes allora <math>L = 0x78</math>
 
Ciò è utile in fase di Decoding, infatti se il primo bit è zero, significa che è stata usata la codifica di L su un solo byte.
[[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))+129 \,\!80_{16}</math>
#si pone nei bytes seguenti ''Len(V)''
 
La formula del punto 3 ha la seguente giustificazione:
*aggiungendo <math>80_{16}</math> si obbliga l'ultimo bit del primo byte di L ad essere 1.
*nei primi 7 bit del primo byte di ''L'' c'è in realtà la lunghezza dei byte restanti di ''L'', infatti <math>Len(Len(V))+1</math> indica proprio la lunghezza di L
[[File:Long Defined Form L.JPG|thumb|upright=3|center|L in Long Defined Form]]
In fase di Decoding per capire che stiamo usando una codifica di L su più byte 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>0000000_2</math>
 
===== Esempio 1 di Codifica di L in ''definite form'' =====
''V'' è codificato su 120 bytes.
 
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' ====
Questo tipo ti encoding è usato quando non si conosce la ''Len(V)'' a priori.
 
In questo caso si procede con i seguenti passi:
*si pone <math>L=10000000_2 = 80_{16}</math>
*si aggiunge ''V''
*in coda a ''V'' si aggiungono 2 bytes di zeri <math>0000_{16}</math>
 
=== Codifica di V ===
La codifica di ''V'', come è stato più volte detto, dipende dal tipo ''T'' e dalla sua definizione tramite sintassi [[ASN.1]] In questa sede 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 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.
 
===== 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
 
Infatti se l'integer è ad es. <math>100_{10}</math> allora si ha: <math>valore =100_{10} \to V = 100_{10} = 64_{16} = 01100100_2</math>. In questo caso il ''bit segno'' è zero e quindi la codifica è corretta.
 
Se invece l'integer è ad es. 250 allora si ha: <math>V = 250_{10} = FA_{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} = FA_{16} = 00FA_{16} = 0000000011111010_2</math>. Come si può notare, aggiungendo gli zeri in testa il ''bit segno'' è correttamente zero.
 
===== INTEGER Negativi =====
Per gli integer negativi si utilizza il ''[[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>
 
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 ottiene <math>10011011_2 + 1_2 = 10011100_2</math>
Quindi <math>valore = -100 \to V = 10011100_2 = 9C_{16} </math>
 
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>
Quindi <math>valore = -250 \to V = 1111111100000110_2 = FF06_{16}</math>
 
==== 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]].
 
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]]