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
 
(101 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 vedereconsultare collegamenti[https://web.archive.org/web/20081205052919/http://www.oss.com/asn1/booksintro.html esterniOSS 1Nokalva e- 2Books 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>
#si aggiunge un '''1''' ogni 7 bit
#si completa il byte con un 0 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.
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
 
[[File:Altribytes T.JPG|thumb|upright==== 2.3|center|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 1 in testa
 
[[immagine:Altribytes_T.JPG |thumb|400px|center|Altri bytes di T]]
 
Ad es. se ID = 250 in base 10, allora:
#<math>250_{10} = FA_{16} = 11111010_2</math>
#250 = 0xFA = 11111010
#<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èperché <math>ID = 250250_{10}</math>
 
In definitiva in questo caso <math>T = DF81FA_{16}</math> ed è di 3 [[byte]].
 
=== Codifica di L ===
In definitiva in questo caso T = 0xDF81FA ed è di 3 bytes
In questa sezione si indica con ''Len(V)'' il numero di byte di ''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'', altrimenti si applica la codifica ''indefinite length''. La prima tecnica è preferibile in quanto permette un Decoding più semplice.
 
==== CodificaEncoding 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.
 
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))+ 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]]