BER Basic Encoding Rules
L'encodage des données ASN-1 est réalisé selon l'algorithme BER. Il est décrit en détails dans la recommandation UIT-T X.209.
Les bits de chaque octets sont numérotés de 8 à 1 avec 8 = MSB et 1 = LSB
8 |
7 |
6 |
5 |
4 |
3 |
2 |
1 |
La structure repose sur le principe de codage TLV (Type, Longueur, Donnée ou Type, Length, Data). La recommandation UIT-T X.209 utilise la terminologie Idendificateur, Longueur, Contenu ou encore Identifier, Length, Content.
Identifier |
Length |
Content |
Le champ Length indique le nombre d'octets du champ Content
Il existe une alternative qui utilise un marqueur de fin :
Identifier |
Length 'Terminated' |
Content |
End marker |
Identifier |
Length |
Content |
||
>=1 octet |
>= 1 octet |
>= 1 octet |
||
B8-7 |
B6 |
B5-1 |
|
|
Class |
Form |
Tag number 0 0000-1 1110 (0-30) |
||
00=Universal |
0=Primitive |
|||
01=Application |
1=Constructed |
|||
|
|
Les types communs (universal) sont les suivants
Form (F) |
0 |
1 |
Primitive |
Constructed |
Class |
00 F |
01 0 |
10 0 |
11 0 |
Universal |
Application |
Context-Specific |
Private |
|
Indicator |
|
|
|
|
0 0000 |
N.U. |
|
|
|
0 0001 |
BOOLEAN(1) |
|
|
|
0 0010 |
INTEGER(2) |
|
|
|
0 0011 |
BITSTRING(3) |
|
|
|
0 0100 |
OCTETSTRING(4) |
|
|
|
0 0101 |
NULL(5) |
|
|
|
0 0110 |
OID(6) |
|
|
|
x 1111 |
Type étendu |
Type étendu |
Type étendu |
Type étendu |
1 0000 |
SEQUENCE(30) (F=1) |
|
|
|
Par défaut, le tag du type est codé sur 5 bits (0-30). Si on doit utiliser une valeur de tag supérieure à 30, on utilise le codage de type étendu:
Premier octet : Les champs Class and Form, sont conformes à la demande. Le champ Tag est forcé à 31 (1 1111 soit 0x1F)
Octets suivants : Ils encodent le numéro du tag de la façon suivante :
Le bit 8 est à 1, sauf pour le dernier octet, qui est à 0.
Les bits 7 a 1 de chaque octets supportent la valeur numérique du tag cadrée à droite (bit 1 du dernier octet).
Exemple : soit à encoder le type « Appplication 293 »
293 = $125
Class |
Form |
Tag |
8 |
7 |
6 |
5 |
4 |
3 |
2 |
1 |
8 |
7 |
6 |
5 |
4 |
3 |
2 |
1 |
01 |
1 |
1 1111 |
1 |
0 |
0 |
0 |
0 |
0 |
1 |
0 |
0 |
0 |
1 |
0 |
0 |
1 |
0 |
1 |
7F |
82 |
25 |
||||||||||||||||
Entête |
Suite |
Dernier |
Il existe 2 types de longueurs:
Longueur définie (Obligatoire avec les 'Primitive')
Longueur non définie
La longueur est codée dans un ou plusieurs octets. Le format utilisant 1 octet est appelé Format Court (Short Form), et le format utilisant plus d'un octet est appelé Format Long (Long Form)
Ce format utilise un octet unique.
Le bit 8 est forcé à 0.
La longueur est codée dans les bits 7 à 1 (0 à 127)
Exemple : L=16 ($10)
8 |
7 |
6 |
5 |
4 |
3 |
2 |
1 |
0 |
0 |
0 |
1 |
0 |
0 |
0 |
0 |
10 |
Ce format utilise un octet d'entête et des octets suivants.
L'octet d'entête, est composé de la façon suivante
Le bit 8 est forcé à 1
Les bits 7 à 1 supportent une valeur numérique (1-126) repésentant la taille du paramètre 'longueur'1.
La valeur 11111111 est interdite2.
Les octets suivants sont codés ainsi
Le bit 8 est forcé à 1 (pas le dernier) ou à 0 (le dernier)
Les bits 7 à 1 supportent une valeur numérique (0-127) encodant le paramètre 'longueur'
Exemple L=$C9 (201)
8 |
7 |
6 |
5 |
4 |
3 |
2 |
1 |
8 |
7 |
6 |
5 |
4 |
3 |
2 |
1 |
8 |
7 |
6 |
5 |
4 |
3 |
2 |
1 |
|
1 |
0 |
0 |
0 |
0 |
0 |
1 |
0 |
1 |
0 |
0 |
0 |
0 |
1 |
1 |
0 |
0 |
0 |
0 |
0 |
1 |
0 |
0 |
1 |
|
82 |
86 |
9 |
||||||||||||||||||||||
1 = Extension |
1 = Extension |
0 = Dernier |
||||||||||||||||||||||
000 0010 (2) = 2 octets |
000 0110 |
000 1001 |
||||||||||||||||||||||
|
00 0011 0000 1001 = C9 |
Dans ce cas, le champ longueur est unique et vaut [80],
8 |
7 |
6 |
5 |
4 |
3 |
2 |
1 |
1 |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
80 |
Ce champ peut contenir 0, 1 ou plus d'octets. Les donnéees sont celles définies par la spécifications ASN-1.
Le marqueur de fin de contenu est une séquence [00 00].
8 |
7 |
6 |
5 |
4 |
3 |
2 |
1 |
8 |
7 |
6 |
5 |
4 |
3 |
2 |
1 |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
00 |
00 |
Le codage de FALSE est 0
Le codage de TRUE est Différent de 0 (1-255)
FALSE / TRUE
T |
L |
V |
BOOLEAN |
1 |
FALSE |
01 |
01 |
0 |
BOOLEAN |
1 |
TRUE |
01 |
01 |
FF |
On cherche toujours a réduire la taille d'un integer au minimum indispensable.
Correct
$1234
T |
L |
V |
INTEGER |
2 |
$1234 |
02 |
02 |
12 34 |
Non optimisé.
$1234
T |
L |
V |
INTEGER |
3 |
$1234 |
02 |
03 |
00 12 34 |
Idem INTEGER
Les données de type BITSTRING peuvent être Primitive ou Constructed. Elles sont encodées de la façon suivante :
Un octet d'entete obligatoire suivit de 0, 1 ou plus d'octets suivants.
ATTENTION!
Le champ d'entête étant obligatoire, le champ length indique le nombre d'octets de données sans l'octet d'entete.
L'octet d'entete encode le nombre de bits inutilisés (0-7) du dernier octet
Chaque octet porte un maximum de 8 bits utiles (MSB à gauche, c'est à dire en B8). Le champ de bit est cadré à gauche. Le premier bit est en octet.0.8. Les bits non utilisés sont forcés à 0.
Exemple : soit à transmettre un champ de 4 bits de valeur 0101
Ces bits sont numérotés de 1 à 4
T |
L |
V |
|
BITSTRING |
2 |
4 |
0101 ---- |
03 |
02 |
04 |
50 |
Soit à encoder :
« Hello »
T |
L |
V |
OCTETSTRING |
5 |
'h', 'e', 'l', 'l', 'o' (ASCII) |
04 |
05 |
68 65 6C 6C 6F |
ANNEXE
1Dans la pratique, on ne devrait pas dépasser les valeurs 2 ou 3
2Pour des extensions futures