Aller au contenu principal

3. Specification of the CBOR Encoding (Spécification de l'encodage CBOR)

Les éléments de données CBOR (Section 2) sont encodés dans ou décodés à partir de chaînes d'octets contenant des éléments de données encodés bien formés, comme décrit dans cette section. L'encodage est résumé dans le tableau 7 de l'Annexe B, indexé par l'octet initial. Les encodeurs doivent (MUST) ne produire que des éléments de données encodés bien formés. Lorsqu'un décodeur rencontre une entrée qui n'est pas un élément de données CBOR encodé bien formé, il ne doit pas (MUST NOT) retourner un élément de données décodé (cela n'enlève rien à l'utilité des outils de diagnostic et de récupération qui peuvent fournir des informations à partir d'éléments de données CBOR encodés corrompus).

L'octet initial (Initial Byte) de chaque élément de données encodé contient des informations sur le type majeur (Major Type, 3 bits supérieurs, décrits dans la Section 3.1) et les informations supplémentaires (Additional Information, 5 bits inférieurs). Sauf quelques exceptions, la valeur des informations supplémentaires décrit comment charger un entier non signé "argument" (Argument):

Inférieur à 24: La valeur de l'argument est la valeur des informations supplémentaires.

24, 25, 26 ou 27: La valeur de l'argument est stockée respectivement dans les 1, 2, 4 ou 8 octets suivants, en ordre des octets réseau. Pour le type majeur 7 et les valeurs d'informations supplémentaires 25, 26, 27, ces octets ne sont pas utilisés comme argument entier, mais comme valeur à virgule flottante (voir Section 3.3).

28, 29, 30: Ces valeurs sont réservées pour les ajouts futurs au format CBOR. Dans la version actuelle de CBOR, l'élément encodé n'est pas bien formé.

31: Aucune valeur d'argument n'est dérivée. Si le type majeur est 0, 1 ou 6, l'élément encodé n'est pas bien formé. Pour les types majeurs 2 à 5, la longueur de l'élément est indéfinie (Indefinite), pour le type majeur 7, cet octet ne constitue pas du tout un élément de données, mais termine un élément de longueur indéfinie; tout cela est décrit dans la Section 3.2.

L'octet initial et tous les octets supplémentaires consommés pour construire l'argument sont collectivement appelés l'en-tête (Head) de l'élément de données.

La signification de cet argument dépend du type majeur. Par exemple, dans le type majeur 0, l'argument est la valeur de l'élément de données lui-même (dans le type majeur 1, la valeur de l'élément de données est calculée à partir de l'argument); dans les types majeurs 2 et 3, il donne la longueur en octets des données de chaîne suivantes; dans les types majeurs 4 et 5, il est utilisé pour déterminer le nombre d'éléments de données inclus.

Si la séquence d'octets encodés se termine avant la fin de l'élément de données, l'élément n'est pas bien formé. Si, après le décodage de l'élément encodé le plus externe, il reste encore des octets dans la séquence d'octets encodés, l'encodage n'est pas un seul élément CBOR bien formé. Selon l'application, le décodeur peut considérer l'encodage comme mal formé ou signaler uniquement à l'application la position de départ des octets restants.

Les implémentations de décodeurs CBOR peuvent être basées sur une table de saut (Jump Table) contenant toutes les 256 valeurs définies de l'octet initial (Tableau 7). Les décodeurs dans les implémentations limitées peuvent utiliser la structure de l'octet initial et des octets suivants pour implémenter un code plus compact (voir l'Annexe C pour son apparence approximative).

3.1. Major Types (Types majeurs)

Ce qui suit énumère les types majeurs ainsi que les informations supplémentaires liées au type et les autres octets.

Type majeur 0 (Major type 0):

Entier non signé (Unsigned Integer) dans la plage 0..2^64-1 (inclus). La valeur de l'élément encodé est l'argument lui-même. Par exemple, l'entier 10 est représenté comme un seul octet 0b000_01010 (type majeur 0, informations supplémentaires 10). L'entier 500 serait 0b000_11001 (type majeur 0, informations supplémentaires 25) suivi de deux octets 0x01f4, soit 500 en décimal.

Type majeur 1 (Major type 1):

Entier négatif (Negative Integer) dans la plage -2^64..-1 (inclus). La valeur de l'élément est -1 moins l'argument. Par exemple, l'entier -500 serait 0b001_11001 (type majeur 1, informations supplémentaires 25) suivi de deux octets 0x01f3, soit 499 en décimal.

Type majeur 2 (Major type 2):

Chaîne d'octets (Byte String). Le nombre d'octets dans la chaîne est égal à l'argument. Par exemple, une chaîne d'octets de longueur 5 aurait un octet initial de 0b010_00101 (type majeur 2, informations supplémentaires 5 pour la longueur), suivi de 5 octets de contenu binaire. Une chaîne d'octets de longueur 500 aurait 3 octets initiaux 0b010_11001 (type majeur 2, informations supplémentaires 25 pour une longueur à deux octets) suivis de deux octets 0x01f4 pour la longueur 500, puis suivis de 500 octets de contenu binaire.

Type majeur 3 (Major type 3):

Chaîne de texte (Text String), encodée en UTF-8 [RFC3629] (Section 2). Le nombre d'octets dans la chaîne est égal à l'argument. Les chaînes contenant des séquences UTF-8 invalides sont bien formées mais invalides (Section 1.2). Ce type est fourni pour les systèmes qui doivent interpréter ou afficher du texte lisible par l'homme, et permet de distinguer les octets non structurés du texte avec un jeu de caractères spécifié (Unicode) et un encodage (UTF-8). Contrairement aux formats comme JSON, les caractères Unicode dans ce type ne sont jamais échappés. Par conséquent, le caractère de saut de ligne (U+000A) est toujours représenté dans une chaîne comme l'octet 0x0a, et non comme les octets 0x5c6e (caractères "\" et "n") ou 0x5c7530303061 (caractères "\", "u", "0", "0", "0" et "a").

Type majeur 4 (Major type 4):

Tableau d'éléments de données (Array). Dans d'autres formats, les tableaux sont également appelés listes (List), séquences (Sequence) ou tuples (Tuple) ("CBOR sequence" est quelque chose de légèrement différent, voir [RFC8742]). L'argument est le nombre d'éléments de données dans le tableau. Les éléments du tableau n'ont pas besoin d'être tous du même type. Par exemple, un tableau de 10 éléments de type arbitraire aurait un octet initial de 0b100_01010 (type majeur 4, informations supplémentaires 10 pour la longueur), suivi des 10 éléments restants.

Type majeur 5 (Major type 5):

Carte de paires d'éléments de données (Map). Les cartes sont également appelées tables (Table), dictionnaires (Dictionary), hachages (Hash) ou objets (Object, en JSON). Une carte est composée de paires d'éléments de données, chaque paire contenant une clé (Key), suivie d'une valeur (Value). L'argument est le nombre de paires d'éléments de données dans la carte. Par exemple, une carte avec 9 paires aurait un octet initial de 0b101_01001 (type majeur 5, informations supplémentaires 9 pour les paires), suivi des 18 éléments restants. Le premier élément est la première clé, le deuxième élément est la première valeur, le troisième élément est la deuxième clé, et ainsi de suite. Comme les éléments d'une carte viennent par paires, leur nombre total est toujours pair: une carte contenant un nombre impair d'éléments (sans élément de données de valeur après le dernier élément de données de clé) n'est pas bien formée. Une carte avec des clés en double peut être bien formée mais n'est pas valide et conduit à un décodage indéterminé; voir également Section 5.6.

Type majeur 6 (Major type 6):

Élément de données étiqueté (Tagged Data Item, "tag"), dont le numéro d'étiquette (Tag Number) est un entier dans la plage 0..2^64-1 (inclus), qui est l'argument, et dont l'élément de données inclus (contenu d'étiquette, Tag Content) est le seul élément de données encodé après l'en-tête. Voir Section 3.4.

Type majeur 7 (Major type 7):

Nombres à virgule flottante et valeurs simples, ainsi que le code d'arrêt "break". Voir Section 3.3.

Ces huit types majeurs forment un tableau simple montrant lesquelles des 256 valeurs possibles de l'octet initial d'un élément de données sont utilisées (Tableau 7).

Dans les types majeurs 6 et 7, de nombreuses valeurs possibles sont réservées pour les spécifications futures. Pour plus d'informations sur ces valeurs, voir Section 9.

Le Tableau 1 résume les types majeurs définis par CBOR, en ignorant temporairement la Section 3.2. Le nombre N dans ce tableau représente l'argument.

+============+=======================+=========================+
| Type | Signification | Contenu |
| majeur | | |
+============+=======================+=========================+
| 0 | Entier non signé N | - |
+------------+-----------------------+-------------------------+
| 1 | Entier négatif -1-N | - |
+------------+-----------------------+-------------------------+
| 2 | Chaîne d'octets | N octets |
+------------+-----------------------+-------------------------+
| 3 | Chaîne de texte | N octets (texte UTF-8) |
+------------+-----------------------+-------------------------+
| 4 | Tableau | N éléments de données |
| | | (éléments) |
+------------+-----------------------+-------------------------+
| 5 | Carte | 2N éléments de données |
| | | (paires clé/valeur) |
+------------+-----------------------+-------------------------+
| 6 | Étiquette numéro N | 1 élément de données |
+------------+-----------------------+-------------------------+
| 7 | Valeur simple/ | - |
| | virgule flottante | |
+------------+-----------------------+-------------------------+

Tableau 1: Aperçu de l'utilisation à longueur fixe des types majeurs CBOR (N = argument)

3.2. Indefinite Lengths for Some Major Types (Longueurs indéfinies pour certains types majeurs)

Quatre éléments CBOR (tableaux, cartes, chaînes d'octets et chaînes de texte) peuvent être encodés avec une longueur indéfinie (Indefinite Length) en utilisant la valeur d'informations supplémentaires 31. Ceci est utile lorsqu'il est nécessaire de commencer l'encodage de cet élément avant de connaître le nombre d'éléments dans un tableau ou une carte, ou la longueur totale d'une chaîne. (La capacité de commencer à envoyer un élément de données avant de connaître tout le contenu de l'élément de données est souvent appelée "streaming" dans cet élément de données).

Les tableaux et cartes de longueur indéfinie sont traités différemment des chaînes de longueur indéfinie (chaînes d'octets et chaînes de texte).

3.2.1. The "break" Stop Code (Code d'arrêt "break")

Le code d'arrêt "break" est encodé avec le type majeur 7 et la valeur d'informations supplémentaires 31 (0b111_11111). Il n'est pas lui-même un élément de données: il s'agit simplement d'une caractéristique syntaxique pour fermer un élément de longueur indéfinie.

Si le code d'arrêt "break" apparaît à une position où un élément de données est attendu, mais pas directement à l'intérieur d'une chaîne, d'un tableau ou d'une carte de longueur indéfinie -- par exemple, directement à l'intérieur d'un tableau ou d'une carte de longueur fixe -- l'élément contenant n'est pas bien formé.

3.2.2. Indefinite-Length Arrays and Maps (Tableaux et cartes de longueur indéfinie)

Les tableaux et cartes de longueur indéfinie sont spécifiés avec leur type majeur et la valeur d'informations supplémentaires 31, suivis d'une séquence de longueur arbitraire de zéro ou plusieurs éléments pour les tableaux, ou de paires clé/valeur pour les cartes, finalement terminée par un code d'arrêt "break" (Section 3.2.1). En d'autres termes, les tableaux et cartes de longueur indéfinie ressemblent aux autres tableaux et cartes, sauf qu'ils commencent par la valeur d'informations supplémentaires 31 et se terminent par un code d'arrêt "break".

3.2.3. Indefinite-Length Byte Strings and Text Strings (Chaînes d'octets et chaînes de texte de longueur indéfinie)

Encodage des chaînes de longueur indéfinie:

  • Octet de type majeur (valeur d'informations supplémentaires 31) + zéro ou plusieurs blocs de chaîne de longueur fixe + code d'arrêt "break"
  • L'élément de données final est la concaténation de tous les blocs
  • Les chaînes de longueur indéfinie ne peuvent pas être imbriquées entre les blocs
  • Chaque bloc d'une chaîne de texte doit commencer à une limite de point de code Unicode (les octets UTF-8 ne peuvent pas être divisés entre les blocs)

Exemple:

5F              -- Début chaîne d'octets de longueur indéfinie
44 -- Chaîne d'octets de longueur 4
aabbccdd -- Contenu d'octets
43 -- Chaîne d'octets de longueur 3
eeff99 -- Contenu d'octets
FF -- "break"

Résultat du décodage: Une seule chaîne d'octets de 7 octets 0xaabbccddeeff99

3.2.4. Summary of Indefinite-Length Use of Major Types (Résumé de l'utilisation de longueur indéfinie)

Tableau 2: Utilisation de longueur indéfinie des types majeurs (informations supplémentaires = 31)

Type majeurSignificationContenu avant "break"
0(non bien formé)-
1(non bien formé)-
2Chaîne d'octetsChaînes d'octets de longueur fixe
3Chaîne de texteChaînes de texte de longueur fixe
4TableauÉléments de données (éléments)
5CarteÉléments de données (paires clé/valeur)
6(non bien formé)-
7Code d'arrêt "break"-

Points clés:

  • Les types majeurs 0, 1, 6 ne supportent pas la longueur indéfinie
  • Les types majeurs 2-5 supportent l'encodage de longueur indéfinie
  • La longueur indéfinie permet le streaming, commençant l'encodage avant de connaître la longueur totale

3.3. Floating-Point Numbers and Values with No Content (Nombres à virgule flottante et valeurs sans contenu)

Utilisation spéciale du type majeur 7:

Le type majeur 7 est utilisé pour encoder les nombres à virgule flottante et les valeurs simples:

Valeurs simples (Simple Values):

  • false (20), true (21), null (22), undefined (23)
  • Informations supplémentaires 0-19: Valeurs simples non attribuées
  • Informations supplémentaires 24: Extension de valeur simple d'un octet (valeurs 32-255)

Encodage à virgule flottante:

  • Informations supplémentaires 25: Nombre à virgule flottante demi-précision (IEEE 754 binary16, 2 octets)
  • Informations supplémentaires 26: Nombre à virgule flottante simple précision (IEEE 754 binary32, 4 octets)
  • Informations supplémentaires 27: Nombre à virgule flottante double précision (IEEE 754 binary64, 8 octets)

Exemples de valeurs spéciales:

  • false: 0xF4
  • true: 0xF5
  • null: 0xF6
  • undefined: 0xF7
  • Nombre à virgule flottante 0.0: 0xF90000 (demi-précision) ou 0xFA00000000 (simple précision)

Considérations de conception:

  • Fournit plusieurs options de précision pour optimiser la taille de l'encodage
  • Supporte toutes les valeurs spéciales IEEE 754 (NaN, Infinity, etc.)
  • Les valeurs simples fournissent un encodage compact pour les valeurs booléennes et nulles courantes

3.4. Tagging of Items (Étiquetage des éléments)

Le mécanisme d'étiquette (Tags) est utilisé pour ajouter des informations sémantiques aux éléments de données.

Structure d'étiquette:

  • Type majeur 6 + numéro d'étiquette (comme argument) + contenu d'étiquette (un élément de données)
  • Plage de numéro d'étiquette: 0 à 2^64-1

Exemples d'étiquettes standard:

N° d'étiquetteSémantiqueExemple
0Chaîne date-heure RFC 3339"2013-03-21T20:04:00Z"
1Horodatage Unix (secondes d'époque)1363896240
2Bignum positif (Positive Bignum)18446744073709551616
3Bignum négatif (Negative Bignum)-18446744073709551617
4Fraction décimale[e, m] signifie m×10^e
5Bigfloat (Bigfloat)[e, m] signifie m×2^e

3.4.1-3.4.6 Types d'étiquettes détaillés

Étiquettes date-heure (0 et 1):

  • Étiquette 0: Date-heure au format texte (format RFC 3339)
  • Étiquette 1: Horodatage au format numérique (secondes d'époque Unix)

Étiquettes bignum (2 et 3):

  • Pour représenter des nombres en dehors de la plage des entiers 64 bits
  • Le contenu de l'étiquette est une chaîne d'octets représentant la valeur numérique en ordre gros-boutiste

Étiquettes d'extension numérique (4 et 5):

  • Fraction décimale: Représentation exacte des nombres décimaux
  • Bigfloat: Nombres à virgule flottante binaire de précision arbitraire

Autres étiquettes couramment utilisées:

  • Étiquettes 21-23: Indices d'encodage base64
  • Étiquette 24: Élément de données CBOR encodé
  • Étiquette 32: URI
  • Étiquette 55799: Identification CBOR auto-descriptive

Extensibilité:

  • Les étiquettes sont gérées par le registre IANA
  • Les applications peuvent définir des étiquettes privées (éviter les conflits)
  • Les décodeurs peuvent supporter sélectivement les étiquettes, les étiquettes inconnues peuvent être transmises à l'application

Résumé du Chapitre 3:

Ce chapitre définit la spécification complète de l'encodage CBOR, y compris:

  1. Règles d'encodage pour 8 types majeurs
  2. Mécanisme d'encodage de longueur indéfinie
  3. Représentation des nombres à virgule flottante et des valeurs simples
  4. Système d'extension d'étiquettes

Ces conceptions rendent CBOR à la fois compact et flexible, adapté à l'Internet des objets et aux environnements contraints.