3. Specification of the CBOR Encoding (Specifica della codifica CBOR)
Gli elementi di dati CBOR (Sezione 2) vengono codificati o decodificati da stringhe di byte contenenti elementi di dati codificati ben formati, come descritto in questa sezione. La codifica è riassunta nella Tabella 7 dell'Appendice B, indicizzata dal byte iniziale. I codificatori devono (MUST) produrre solo elementi di dati codificati ben formati. Quando un decodificatore incontra un input che non è un elemento di dati CBOR codificato ben formato, non deve (MUST NOT) restituire un elemento di dati decodificato (questo non diminuisce l'utilità degli strumenti di diagnostica e recupero che possono fornire alcune informazioni da elementi di dati CBOR codificati corrotti).
Il byte iniziale (Initial Byte) di ogni elemento di dati codificato contiene informazioni sul tipo principale (Major Type, 3 bit superiori, descritti nella Sezione 3.1) e informazioni aggiuntive (Additional Information, 5 bit inferiori). Salvo poche eccezioni, il valore delle informazioni aggiuntive descrive come caricare un intero senza segno "argomento" (Argument):
Inferiore a 24: Il valore dell'argomento è il valore delle informazioni aggiuntive.
24, 25, 26 o 27: Il valore dell'argomento è memorizzato rispettivamente nei successivi 1, 2, 4 o 8 byte, in ordine di byte di rete. Per il tipo principale 7 e i valori delle informazioni aggiuntive 25, 26, 27, questi byte non sono utilizzati come argomento intero, ma come valore in virgola mobile (vedere Sezione 3.3).
28, 29, 30: Questi valori sono riservati per aggiunte future al formato CBOR. Nella versione corrente di CBOR, l'elemento codificato non è ben formato.
31: Non viene derivato alcun valore di argomento. Se il tipo principale è 0, 1 o 6, l'elemento codificato non è ben formato. Per i tipi principali da 2 a 5, la lunghezza dell'elemento è indefinita (Indefinite), per il tipo principale 7, questo byte non costituisce affatto un elemento di dati, ma termina un elemento di lunghezza indefinita; tutto questo è descritto nella Sezione 3.2.
Il byte iniziale e tutti i byte aggiuntivi consumati per costruire l'argomento sono collettivamente chiamati intestazione (Head) dell'elemento di dati.
Il significato di questo argomento dipende dal tipo principale. Ad esempio, nel tipo principale 0, l'argomento è il valore dell'elemento di dati stesso (nel tipo principale 1, il valore dell'elemento di dati viene calcolato dall'argomento); nei tipi principali 2 e 3, fornisce la lunghezza in byte dei dati di stringa successivi; nei tipi principali 4 e 5, viene utilizzato per determinare il numero di elementi di dati inclusi.
Se la sequenza di byte codificati termina prima della fine dell'elemento di dati, l'elemento non è ben formato. Se, dopo aver decodificato l'elemento codificato più esterno, rimangono ancora byte nella sequenza di byte codificati, la codifica non è un singolo elemento CBOR ben formato. A seconda dell'applicazione, il decodificatore può considerare la codifica come mal formata o semplicemente segnalare all'applicazione la posizione di inizio dei byte rimanenti.
Le implementazioni di decodificatori CBOR possono essere basate su una tabella di salto (Jump Table) contenente tutti i 256 valori definiti del byte iniziale (Tabella 7). I decodificatori nelle implementazioni limitate possono utilizzare la struttura del byte iniziale e dei byte successivi per implementare codice più compatto (vedere Appendice C per il suo aspetto approssimativo).
3.1. Major Types (Tipi principali)
Di seguito sono elencati i tipi principali insieme alle informazioni aggiuntive relative al tipo e altri byte.
Tipo principale 0 (Major type 0):
Intero senza segno (Unsigned Integer) nell'intervallo 0..2^64-1 (incluso). Il valore dell'elemento codificato è l'argomento stesso. Ad esempio, l'intero 10 è rappresentato come un singolo byte 0b000_01010 (tipo principale 0, informazioni aggiuntive 10). L'intero 500 sarebbe 0b000_11001 (tipo principale 0, informazioni aggiuntive 25) seguito da due byte 0x01f4, ovvero 500 in decimale.
Tipo principale 1 (Major type 1):
Intero negativo (Negative Integer) nell'intervallo -2^64..-1 (incluso). Il valore dell'elemento è -1 meno l'argomento. Ad esempio, l'intero -500 sarebbe 0b001_11001 (tipo principale 1, informazioni aggiuntive 25) seguito da due byte 0x01f3, ovvero 499 in decimale.
Tipo principale 2 (Major type 2):
Stringa di byte (Byte String). Il numero di byte nella stringa è uguale all'argomento. Ad esempio, una stringa di byte di lunghezza 5 avrebbe un byte iniziale di 0b010_00101 (tipo principale 2, informazioni aggiuntive 5 per la lunghezza), seguito da 5 byte di contenuto binario. Una stringa di byte di lunghezza 500 avrebbe 3 byte iniziali 0b010_11001 (tipo principale 2, informazioni aggiuntive 25 per lunghezza a due byte) seguito da due byte 0x01f4 per la lunghezza 500, quindi seguito da 500 byte di contenuto binario.
Tipo principale 3 (Major type 3):
Stringa di testo (Text String), codificata in UTF-8 [RFC3629] (Sezione 2). Il numero di byte nella stringa è uguale all'argomento. Le stringhe contenenti sequenze UTF-8 non valide sono ben formate ma non valide (Sezione 1.2). Questo tipo è fornito per i sistemi che devono interpretare o visualizzare testo leggibile dall'uomo e consente di distinguere tra byte non strutturati e testo con un set di caratteri specificato (Unicode) e una codifica (UTF-8). A differenza di formati come JSON, i caratteri Unicode in questo tipo non vengono mai sottoposti a escape. Pertanto, il carattere di nuova riga (U+000A) è sempre rappresentato in una stringa come byte 0x0a, non come byte 0x5c6e (caratteri "\" e "n") o 0x5c7530303061 (caratteri "\", "u", "0", "0", "0" e "a").
Tipo principale 4 (Major type 4):
Array di elementi di dati (Array). In altri formati, gli array sono anche chiamati liste (List), sequenze (Sequence) o tuple (Tuple) ("CBOR sequence" è qualcosa di leggermente diverso, vedere [RFC8742]). L'argomento è il numero di elementi di dati nell'array. Gli elementi nell'array non devono essere tutti dello stesso tipo. Ad esempio, un array di 10 elementi di tipo arbitrario avrebbe un byte iniziale di 0b100_01010 (tipo principale 4, informazioni aggiuntive 10 per la lunghezza), seguito dai 10 elementi rimanenti.
Tipo principale 5 (Major type 5):
Mappa di coppie di elementi di dati (Map). Le mappe sono anche chiamate tabelle (Table), dizionari (Dictionary), hash (Hash) o oggetti (Object, in JSON). Una mappa è composta da coppie di elementi di dati, ciascuna coppia contenente una chiave (Key), seguita da un valore (Value). L'argomento è il numero di coppie di elementi di dati nella mappa. Ad esempio, una mappa con 9 coppie avrebbe un byte iniziale di 0b101_01001 (tipo principale 5, informazioni aggiuntive 9 per le coppie), seguito dai 18 elementi rimanenti. Il primo elemento è la prima chiave, il secondo elemento è il primo valore, il terzo elemento è la seconda chiave e così via. Poiché gli elementi in una mappa vengono in coppie, il loro numero totale è sempre pari: una mappa contenente un numero dispari di elementi (senza elemento di dati valore dopo l'ultimo elemento di dati chiave) non è ben formata. Una mappa con chiavi duplicate può essere ben formata ma non è valida e porta a decodifica indeterminata; vedere anche Sezione 5.6.
Tipo principale 6 (Major type 6):
Elemento di dati etichettato (Tagged Data Item, "tag"), il cui numero di etichetta (Tag Number) è un intero nell'intervallo 0..2^64-1 (incluso), che è l'argomento, e il cui elemento di dati incluso (contenuto dell'etichetta, Tag Content) è il singolo elemento di dati codificato dopo l'intestazione. Vedere Sezione 3.4.
Tipo principale 7 (Major type 7):
Numeri in virgola mobile e valori semplici, nonché il codice di arresto "break". Vedere Sezione 3.3.
Questi otto tipi principali formano una tabella semplice che mostra quali dei 256 possibili valori del byte iniziale di un elemento di dati vengono utilizzati (Tabella 7).
Nei tipi principali 6 e 7, molti valori possibili sono riservati per specifiche future. Per ulteriori informazioni su questi valori, vedere Sezione 9.
La Tabella 1 riassume i tipi principali definiti da CBOR, ignorando temporaneamente la Sezione 3.2. Il numero N in questa tabella rappresenta l'argomento.
+============+=======================+=========================+
| Tipo | Significato | Contenuto |
| principale | | |
+============+=======================+=========================+
| 0 | Intero senza segno N | - |
+------------+-----------------------+-------------------------+
| 1 | Intero negativo -1-N | - |
+------------+-----------------------+-------------------------+
| 2 | Stringa di byte | N byte |
+------------+-----------------------+-------------------------+
| 3 | Stringa di testo | N byte (testo UTF-8) |
+------------+-----------------------+-------------------------+
| 4 | Array | N elementi di dati |
| | | (elementi) |
+------------+-----------------------+-------------------------+
| 5 | Mappa | 2N elementi di dati |
| | | (coppie chiave/valore) |
+------------+-----------------------+-------------------------+
| 6 | Etichetta numero N | 1 elemento di dati |
+------------+-----------------------+-------------------------+
| 7 | Valore semplice/ | - |
| | virgola mobile | |
+------------+-----------------------+-------------------------+
Tabella 1: Panoramica dell'uso a lunghezza fissa dei tipi principali CBOR (N = argomento)
3.2. Indefinite Lengths for Some Major Types (Lunghezze indefinite per alcuni tipi principali)
Quattro elementi CBOR (array, mappe, stringhe di byte e stringhe di testo) possono essere codificati con lunghezza indefinita (Indefinite Length) utilizzando il valore delle informazioni aggiuntive 31. Questo è utile quando è necessario iniziare la codifica di questo elemento prima di conoscere il numero di elementi in un array o mappa, o la lunghezza totale di una stringa. (La capacità di iniziare a inviare un elemento di dati prima di conoscere l'intero contenuto dell'elemento di dati è spesso chiamata "streaming" all'interno di quell'elemento di dati).
Gli array e le mappe di lunghezza indefinita sono trattati in modo diverso rispetto alle stringhe di lunghezza indefinita (stringhe di byte e stringhe di testo).
3.2.1. The "break" Stop Code (Codice di arresto "break")
Il codice di arresto "break" è codificato con il tipo principale 7 e il valore delle informazioni aggiuntive 31 (0b111_11111). Non è esso stesso un elemento di dati: è solo una caratteristica sintattica per chiudere un elemento di lunghezza indefinita.
Se il codice di arresto "break" appare in una posizione in cui è previsto un elemento di dati, ma non direttamente all'interno di una stringa, array o mappa di lunghezza indefinita -- ad esempio, direttamente all'interno di un array o mappa di lunghezza fissa -- l'elemento contenente non è ben formato.
3.2.2. Indefinite-Length Arrays and Maps (Array e mappe di lunghezza indefinita)
Gli array e le mappe di lunghezza indefinita sono specificati con il loro tipo principale e il valore delle informazioni aggiuntive 31, seguiti da una sequenza di lunghezza arbitraria di zero o più elementi per gli array, o coppie chiave/valore per le mappe, infine terminata da un codice di arresto "break" (Sezione 3.2.1). In altre parole, gli array e le mappe di lunghezza indefinita appaiono uguali agli altri array e mappe, tranne che iniziano con il valore delle informazioni aggiuntive 31 e terminano con un codice di arresto "break".
3.2.3. Indefinite-Length Byte Strings and Text Strings (Stringhe di byte e stringhe di testo di lunghezza indefinita)
Codifica delle stringhe di lunghezza indefinita:
- Byte di tipo principale (valore informazioni aggiuntive 31) + zero o più blocchi di stringa di lunghezza fissa + codice di arresto "break"
- L'elemento di dati finale è la concatenazione di tutti i blocchi
- Le stringhe di lunghezza indefinita non possono essere annidate tra i blocchi
- Ogni blocco di una stringa di testo deve iniziare su un confine di punto di codice Unicode (i byte UTF-8 non possono essere divisi tra i blocchi)
Esempio:
5F -- Inizio stringa di byte di lunghezza indefinita
44 -- Stringa di byte di lunghezza 4
aabbccdd -- Contenuto byte
43 -- Stringa di byte di lunghezza 3
eeff99 -- Contenuto byte
FF -- "break"
Risultato della decodifica: Una singola stringa di byte di 7 byte 0xaabbccddeeff99
3.2.4. Summary of Indefinite-Length Use of Major Types (Riepilogo dell'uso di lunghezza indefinita)
Tabella 2: Uso di lunghezza indefinita dei tipi principali (informazioni aggiuntive = 31)
| Tipo principale | Significato | Contenuto prima di "break" |
|---|---|---|
| 0 | (non ben formato) | - |
| 1 | (non ben formato) | - |
| 2 | Stringa di byte | Stringhe di byte di lunghezza fissa |
| 3 | Stringa di testo | Stringhe di testo di lunghezza fissa |
| 4 | Array | Elementi di dati (elementi) |
| 5 | Mappa | Elementi di dati (coppie chiave/valore) |
| 6 | (non ben formato) | - |
| 7 | Codice di arresto "break" | - |
Punti chiave:
- I tipi principali 0, 1, 6 non supportano la lunghezza indefinita
- I tipi principali 2-5 supportano la codifica di lunghezza indefinita
- La lunghezza indefinita consente lo streaming, iniziando la codifica prima di conoscere la lunghezza totale
3.3. Floating-Point Numbers and Values with No Content (Numeri in virgola mobile e valori senza contenuto)
Uso speciale del tipo principale 7:
Il tipo principale 7 è utilizzato per codificare numeri in virgola mobile e valori semplici:
Valori semplici (Simple Values):
false(20),true(21),null(22),undefined(23)- Informazioni aggiuntive 0-19: Valori semplici non assegnati
- Informazioni aggiuntive 24: Estensione valore semplice a un byte (valori 32-255)
Codifica in virgola mobile:
- Informazioni aggiuntive 25: Numero in virgola mobile a mezza precisione (IEEE 754 binary16, 2 byte)
- Informazioni aggiuntive 26: Numero in virgola mobile a precisione singola (IEEE 754 binary32, 4 byte)
- Informazioni aggiuntive 27: Numero in virgola mobile a precisione doppia (IEEE 754 binary64, 8 byte)
Esempi di valori speciali:
false: 0xF4true: 0xF5null: 0xF6undefined: 0xF7- Numero in virgola mobile 0.0: 0xF90000 (mezza precisione) o 0xFA00000000 (precisione singola)
Considerazioni di progettazione:
- Fornisce più opzioni di precisione per ottimizzare la dimensione di codifica
- Supporta tutti i valori speciali IEEE 754 (NaN, Infinity, ecc.)
- I valori semplici forniscono codifica compatta per valori booleani e nulli comuni
3.4. Tagging of Items (Etichettatura degli elementi)
Il meccanismo di etichetta (Tags) è utilizzato per aggiungere informazioni semantiche agli elementi di dati.
Struttura dell'etichetta:
- Tipo principale 6 + numero di etichetta (come argomento) + contenuto dell'etichetta (un elemento di dati)
- Intervallo del numero di etichetta: da 0 a 2^64-1
Esempi di etichette standard:
| N. etichetta | Semantica | Esempio |
|---|---|---|
| 0 | Stringa data-ora RFC 3339 | "2013-03-21T20:04:00Z" |
| 1 | Timestamp Unix (secondi epoch) | 1363896240 |
| 2 | Bignum positivo (Positive Bignum) | 18446744073709551616 |
| 3 | Bignum negativo (Negative Bignum) | -18446744073709551617 |
| 4 | Frazione decimale | [e, m] significa m×10^e |
| 5 | Bigfloat (Bigfloat) | [e, m] significa m×2^e |
3.4.1-3.4.6 Tipi di etichette dettagliati
Etichette data-ora (0 e 1):
- Etichetta 0: Data-ora in formato testo (formato RFC 3339)
- Etichetta 1: Timestamp in formato numerico (secondi epoch Unix)
Etichette bignum (2 e 3):
- Per rappresentare numeri al di fuori dell'intervallo degli interi a 64 bit
- Il contenuto dell'etichetta è una stringa di byte che rappresenta il valore numerico in ordine big-endian
Etichette di estensione numerica (4 e 5):
- Frazione decimale: Rappresentazione esatta di numeri decimali
- Bigfloat: Numeri in virgola mobile binaria di precisione arbitraria
Altre etichette comunemente utilizzate:
- Etichette 21-23: Suggerimenti di codifica base64
- Etichetta 24: Elemento di dati CBOR codificato
- Etichetta 32: URI
- Etichetta 55799: Identificazione CBOR auto-descrittiva
Estensibilità:
- Le etichette sono gestite dal registro IANA
- Le applicazioni possono definire etichette private (evitare conflitti)
- I decodificatori possono supportare selettivamente le etichette, le etichette sconosciute possono essere passate all'applicazione
Riepilogo del Capitolo 3:
Questo capitolo definisce la specifica completa della codifica CBOR, tra cui:
- Regole di codifica per 8 tipi principali
- Meccanismo di codifica a lunghezza indefinita
- Rappresentazione di numeri in virgola mobile e valori semplici
- Sistema di estensione delle etichette
Questi progetti rendono CBOR sia compatto che flessibile, adatto per l'Internet delle cose e ambienti vincolati.