Passa al contenuto principale

2. Specifica della codifica CBOR

Un elemento dati codificato in CBOR è strutturato e codificato come descritto in questa sezione. La codifica è riassunta nella Tabella 5.

Il byte iniziale di ogni elemento dati contiene sia informazioni sul tipo principale (i 3 bit di ordine superiore, descritti nella Sezione 2.1) sia informazioni aggiuntive (i 5 bit di ordine inferiore). Quando il valore delle informazioni aggiuntive è inferiore a 24, esso viene usato direttamente come un piccolo intero senza segno. Quando è da 24 a 27, i byte aggiuntivi per un intero a lunghezza variabile seguono immediatamente; i valori da 24 a 27 delle informazioni aggiuntive specificano che la sua lunghezza è rispettivamente un intero senza segno di 1, 2, 4 o 8 byte. Il valore 31 delle informazioni aggiuntive è usato per gli elementi a lunghezza indefinita, descritti nella Sezione 2.2. I valori da 28 a 30 delle informazioni aggiuntive sono riservati per future espansioni.

In tutti i valori delle informazioni aggiuntive, l'intero risultante viene interpretato in base al tipo principale. Esso può rappresentare i dati effettivi: ad esempio, nei tipi interi, l'intero risultante è usato per il valore stesso. Può invece fornire informazioni sulla lunghezza: ad esempio, nelle stringhe di byte fornisce la lunghezza dei dati della stringa di byte che seguono.

Un'implementazione di decoder CBOR può basarsi su una tabella di salto con tutti i 256 valori definiti per il byte iniziale (Tabella 5). Un decoder in un'implementazione vincolata può invece utilizzare la struttura del byte iniziale e dei byte successivi per un codice più compatto (vedere l'Appendice C per un'idea approssimativa di come potrebbe apparire).

2.1. Tipi principali​

Quanto segue elenca i tipi principali e le informazioni aggiuntive e gli altri byte associati al tipo.

Tipo principale 0: un intero senza segno. Le informazioni aggiuntive di 5 bit sono o l'intero stesso (per i valori delle informazioni aggiuntive da 0 a 23) o la lunghezza dei dati aggiuntivi. Le informazioni aggiuntive 24 indicano che il valore è rappresentato in un uint8_t aggiuntivo, 25 indica un uint16_t, 26 indica un uint32_t e 27 indica un uint64_t. Ad esempio, l'intero 10 è indicato con il singolo byte 0b000_01010 (tipo principale 0, informazioni aggiuntive 10). L'intero 500 sarebbe 0b000_11001 (tipo principale 0, informazioni aggiuntive 25) seguito dai due byte 0x01f4, che è 500 in decimale.

Tipo principale 1: un intero negativo. La codifica segue le regole per gli interi senza segno (tipo principale 0), tranne per il fatto che il valore è poi -1 meno l'intero senza segno codificato. Ad esempio, l'intero -500 sarebbe 0b001_11001 (tipo principale 1, informazioni aggiuntive 25) seguito dai due byte 0x01f3, che è 499 in decimale.

Tipo principale 2: una stringa di byte. La lunghezza della stringa in byte è rappresentata secondo le regole per gli interi positivi (tipo principale 0). Ad esempio, una stringa di byte la cui 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 la cui lunghezza è 500 avrebbe 3 byte iniziali di 0b010_11001 (tipo principale 2, informazioni aggiuntive 25 per indicare una lunghezza di due byte) seguiti dai due byte 0x01f4 per una lunghezza di 500, seguiti da 500 byte di contenuto binario.

Tipo principale 3: una stringa di testo, in particolare una stringa di caratteri Unicode codificata come UTF-8 [RFC3629]. Il formato di questo tipo è identico a quello delle stringhe di byte (tipo principale 2), cioè, come per il tipo principale 2, la lunghezza indica il numero di byte. Questo tipo è fornito per i sistemi che devono interpretare o visualizzare testo leggibile dall'uomo, e consente di differenziare i byte non strutturati dal testo che ha un repertorio e una codifica specificati. A differenza di formati come JSON, i caratteri Unicode in questo tipo non sono mai sottoposti a escape. Pertanto, un carattere di nuova riga (U+000A) è sempre rappresentato in una stringa come il byte 0x0a, e mai come i byte 0x5c6e (i caratteri "" e "n") o come 0x5c7530303061 (i caratteri "", "u", "0", "0", "0" e "a").

Tipo principale 4: un array di elementi dati. Gli array sono anche chiamati liste, sequenze o tuple. La lunghezza dell'array segue le regole per le stringhe di byte (tipo principale 2), tranne per il fatto che la lunghezza indica il numero di elementi dati, non la lunghezza in byte occupata dall'array. Gli elementi di un array non devono essere tutti dello stesso tipo. Ad esempio, un array che contiene 10 elementi di qualsiasi tipo avrebbe un byte iniziale di 0b100_01010 (tipo principale 4, informazioni aggiuntive 10 per la lunghezza) seguito dai 10 elementi rimanenti.

Tipo principale 5: una mappa di coppie di elementi dati. Le mappe sono anche chiamate tabelle, dizionari, hash o oggetti (in JSON). Una mappa è composta da coppie di elementi dati, ciascuna coppia costituita da una chiave immediatamente seguita da un valore. La lunghezza della mappa segue le regole per le stringhe di byte (tipo principale 2), tranne per il fatto che la lunghezza indica il numero di coppie, non la lunghezza in byte occupata dalla mappa. Ad esempio, una mappa che contiene 9 coppie avrebbe un byte iniziale di 0b101_01001 (tipo principale 5, informazioni aggiuntive 9 per il numero di 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. Una mappa che ha chiavi duplicate può essere ben formata, ma non è valida, e pertanto causa una decodifica indeterminata; vedere anche la Sezione 3.7.

Tipo principale 6: etichettatura semantica opzionale di altri tipi principali. Vedere la Sezione 2.4.

Tipo principale 7: numeri in virgola mobile e tipi di dati semplici che non richiedono contenuto, nonché il codice di arresto "break". Vedere la Sezione 2.3.

Questi otto tipi principali producono una semplice tabella che mostra quali dei 256 valori possibili per il byte iniziale di un elemento dati sono utilizzati (Tabella 5).

Nei tipi principali 6 e 7, molti dei valori possibili sono riservati per future specifiche. Vedere la Sezione 7 per maggiori informazioni su questi valori.

2.2. Lunghezze indefinite per alcuni tipi principali​

Quattro elementi CBOR (array, mappe, stringhe di byte e stringhe di testo) possono essere codificati con una lunghezza indefinita utilizzando il valore 31 delle informazioni aggiuntive. Ciò è utile se la codifica dell'elemento deve iniziare prima che siano noti il numero di elementi all'interno dell'array o della mappa, o la lunghezza totale della stringa. (L'applicazione di ciò è spesso indicata come "streaming" all'interno di un elemento dati.)

Gli array e le mappe a lunghezza indefinita sono gestiti diversamente dalle stringhe di byte e dalle stringhe di testo a lunghezza indefinita.

2.2.1. Array e mappe a lunghezza indefinita​

Gli array e le mappe a lunghezza indefinita vengono semplicemente aperti senza indicare il numero di elementi dati che saranno inclusi nell'array o nella mappa, utilizzando il valore 31 delle informazioni aggiuntive. Il byte iniziale del tipo principale e delle informazioni aggiuntive è seguito dagli elementi dell'array o della mappa, esattamente come lo sarebbero in altri array o mappe. La fine dell'array o della mappa è indicata codificando un codice di arresto "break" in un punto in cui sarebbe normalmente stato incluso il successivo elemento dati. Il "break" è codificato con il tipo principale 7 e il valore 31 delle informazioni aggiuntive (0b111_11111) ma non è esso stesso un elemento dati: è solo una caratteristica sintattica per chiudere l'array o la mappa. Vale a dire, il codice di arresto "break" viene dopo l'ultimo elemento dell'array o della mappa, e non può comparire in nessun altro punto al posto di un elemento dati. In questo modo, gli array e le mappe a lunghezza indefinita appaiono identici agli altri array e mappe, tranne per il fatto che iniziano con il valore 31 delle informazioni aggiuntive e terminano con il codice di arresto "break".

Gli array e le mappe con lunghezze indefinite consentono di fornire un numero qualsiasi di elementi (per gli array) e di coppie chiave/valore (per le mappe) prima del codice di arresto "break". Non vi è alcuna restrizione contro l'annidamento di elementi array o mappa a lunghezza indefinita. Un "break" termina un solo elemento, quindi gli elementi annidati a lunghezza indefinita necessitano esattamente di tanti codici di arresto "break" quanti sono i byte di tipo che avviano un elemento a lunghezza indefinita.

Ad esempio, supponiamo che un encoder voglia rappresentare l'array astratto [1, [2, 3], [4, 5]]. La codifica a lunghezza definita sarebbe 0x8301820203820405:

83 -- Array of length 3 01 -- 1 82 -- Array of length 2 02 -- 2 03 -- 3 82 -- Array of length 2 04 -- 4 05 -- 5

La codifica a lunghezza indefinita potrebbe essere applicata indipendentemente a ciascuno dei tre array codificati in questo elemento dati, come richiesto, producendo rappresentazioni quali:

0x9f018202039f0405ffff 9F -- Start indefinite-length array 01 -- 1 82 -- Array of length 2 02 -- 2 03 -- 3 9F -- Start indefinite-length array 04 -- 4 05 -- 5 FF -- "break" (inner array) FF -- "break" (outer array)

0x9f01820203820405ff 9F -- Start indefinite-length array 01 -- 1 82 -- Array of length 2 02 -- 2 03 -- 3 82 -- Array of length 2 04 -- 4 05 -- 5 FF -- "break" 0x83018202039f0405ff 83 -- Array of length 3 01 -- 1 82 -- Array of length 2 02 -- 2 03 -- 3 9F -- Start indefinite-length array 04 -- 4 05 -- 5 FF -- "break"

0x83019f0203ff820405 83 -- Array of length 3 01 -- 1 9F -- Start indefinite-length array 02 -- 2 03 -- 3 FF -- "break" 82 -- Array of length 2 04 -- 4 05 -- 5

Un esempio di mappa a lunghezza indefinita (che per l'appunto ha due coppie chiave/valore) potrebbe essere:

0xbf6346756ef563416d7421ff BF -- Start indefinite-length map 63 -- First key, UTF-8 string length 3 46756e -- "Fun" F5 -- First value, true 63 -- Second key, UTF-8 string length 3 416d74 -- "Amt" 21 -- -2 FF -- "break"

2.2.2. Stringhe di byte e stringhe di testo a lunghezza indefinita​

Le stringhe di byte e le stringhe di testo a lunghezza indefinita sono in realtà una concatenazione di zero o più stringhe di byte o di testo a lunghezza definita ("chunk") che insieme sono trattate come un'unica stringa contigua. Le stringhe a lunghezza indefinita sono aperte con il tipo principale e il valore 31 delle informazioni aggiuntive, ma ciò che segue è una serie di stringhe di byte o di testo che hanno lunghezze definite (i chunk). La fine della serie di chunk è indicata codificando il codice di arresto "break" (0b111_11111) in un punto in cui comparirebbe il chunk successivo della serie. I contenuti dei chunk sono concatenati insieme, e la lunghezza complessiva della stringa a lunghezza indefinita sarà la somma delle lunghezze di tutti i chunk. In sintesi, una stringa a lunghezza indefinita è codificata in modo simile a come sarebbe codificato un array a lunghezza indefinita dei suoi chunk, tranne per il fatto che il tipo principale della stringa a lunghezza indefinita è quello di una stringa (di testo o di byte) e corrisponde ai tipi principali dei suoi chunk.

Per le stringhe di byte a lunghezza indefinita, ogni elemento dati (chunk) tra l'indicatore di lunghezza indefinita e il "break" MUST essere un elemento stringa di byte a lunghezza definita; se il parser vede un tipo di elemento diverso da una stringa di byte prima di vedere il "break", si tratta di un errore.

Ad esempio, si assuma la sequenza:

0b010_11111 0b010_00100 0xaabbccdd 0b010_00011 0xeeff99 0b111_11111

5F -- Start indefinite-length byte string 44 -- Byte string of length 4 aabbccdd -- Bytes content 43 -- Byte string of length 3 eeff99 -- Bytes content FF -- "break"

Dopo la decodifica, ciò produce un'unica stringa di byte con sette byte: 0xaabbccddeeff99.

Le stringhe di testo a lunghezza indefinita si comportano allo stesso modo delle stringhe di byte a lunghezza indefinita, tranne per il fatto che tutti i loro chunk MUST essere stringhe di testo a lunghezza definita. Si noti che ciò implica che i byte di un singolo carattere UTF-8 non possono essere distribuiti tra i chunk: un nuovo chunk può essere iniziato solo al confine di un carattere.

2.3. Numeri in virgola mobile e valori senza contenuto​

Il tipo principale 7 è per due tipi di dati: i numeri in virgola mobile e i "valori semplici" che non richiedono alcun contenuto. Ogni valore delle informazioni aggiuntive di 5 bit nel byte iniziale ha il proprio significato separato, come definito nella Tabella 1. Come i tipi principali per gli interi, gli elementi di questo tipo principale non trasportano dati di contenuto; tutte le informazioni sono nei byte iniziali.

Valore a 5 bitSemantica
0..23Valore semplice (valore 0..23)
24Valore semplice (valore 32..255 nel byte successivo)
25Float IEEE 754 a mezza precisione (seguono 16 bit)
26Float IEEE 754 a precisione singola (seguono 32 bit)
27Float IEEE 754 a doppia precisione (seguono 64 bit)
28-30(Non assegnato)
31codice di arresto "break" per elementi a lunghezza indefinita

Tabella 1: Valori per le informazioni aggiuntive nel tipo principale 7

Come per tutti gli altri tipi principali, il valore a 5 bit 24 indica un'estensione di un singolo byte: è seguito da un byte aggiuntivo per rappresentare il valore semplice. (Per ridurre al minimo la confusione, vengono usati solo i valori da 32 a 255.) Ciò mantiene la struttura dei byte iniziali: come per gli altri tipi principali, la lunghezza di questi dipende sempre dalle informazioni aggiuntive nel primo byte. La Tabella 2 elenca i valori assegnati e disponibili per i tipi semplici.

ValoreSemantica
0..19(Non assegnato)
20Falso
21Vero
22Null
23Valore indefinito
24..31(Riservato)
32..255(Non assegnato)

Tabella 2: Valori semplici

I valori a 5 bit 25, 26 e 27 sono per valori in virgola mobile binari IEEE 754 a 16, 32 e 64 bit. Questi valori in virgola mobile sono codificati nei byte aggiuntivi della dimensione appropriata. (Vedere l'Appendice D per alcune informazioni sul virgola mobile a 16 bit.)

2.4. Etichettatura opzionale degli elementi​

In CBOR, un elemento dati può essere opzionalmente preceduto da un tag per conferirgli semantica aggiuntiva mantenendone la struttura. Il tag è il tipo principale 6 e rappresenta un numero intero come indicato dal valore intero del tag; l'(unico) elemento dati è trasportato come dati di contenuto. Se un tag richiede dati strutturati, questa struttura è codificata nell'elemento dati annidato. La definizione di un tag di solito limita quali tipi di elemento o elementi dati annidati possono essere trasportati da un tag.

I byte iniziali del tag seguono le regole per gli interi positivi (tipo principale 0). Il tag è seguito da un singolo elemento dati di qualsiasi tipo. Ad esempio, supponiamo che una stringa di byte di lunghezza 12 sia contrassegnata con un tag per indicare che è un bignum positivo (Sezione 2.4.2). Ciò sarebbe contrassegnato come 0b110_00010 (tipo principale 6, informazioni aggiuntive 2 per il tag) seguito da 0b010_01100 (tipo principale 2, informazioni aggiuntive 12 per la lunghezza) seguito dai 12 byte del bignum.

I decoder non devono comprendere i tag, e quindi i tag possono avere scarso valore nelle applicazioni in cui l'implementazione che crea un particolare elemento dati CBOR e l'implementazione che decodifica quel flusso conoscono il significato semantico di ogni elemento nel flusso di dati. Il loro scopo principale in questa specifica è definire tipi di dati comuni come le date. Uno scopo secondario è consentire l'etichettatura opzionale quando il decoder è un decoder CBOR generico che potrebbe trarre vantaggio da suggerimenti sul contenuto degli elementi. La comprensione dei tag semantici è opzionale per un decoder; esso può semplicemente saltare i byte iniziali del tag e interpretare l'elemento dati etichettato stesso.

Un tag si applica sempre all'elemento che lo segue direttamente. Quindi, se il tag A è seguito dal tag B, che è seguito dall'elemento dati C, il tag A si applica al risultato dell'applicazione del tag B sull'elemento dati C. Vale a dire, un elemento etichettato è un elemento dati costituito da un tag e un valore. Il contenuto dell'elemento etichettato è l'elemento dati (il valore) che viene etichettato.

IANA mantiene un registro dei valori dei tag come descritto nella Sezione 7.2. La Tabella 3 fornisce un elenco dei valori iniziali, con le definizioni nel resto di questa sezione.

TagElemento datiSemantica
0stringa UTF-8Stringa data/ora standard; vedere la Sezione 2.4.1
1multiploData/ora basata su epoca; vedere la Sezione 2.4.1
2stringa di byteBignum positivo; vedere la Sezione 2.4.2
3stringa di byteBignum negativo; vedere la Sezione 2.4.2
4arrayFrazione decimale; vedere la Sezione 2.4.3
5arrayBigfloat; vedere la Sezione 2.4.3
6..20(Non assegnato)(Non assegnato)
21multiploConversione prevista in codifica base64url; vedere la Sezione 2.4.4.2
22multiploConversione prevista in codifica base64; vedere la Sezione 2.4.4.2
23multiploConversione prevista in codifica base16; vedere la Sezione 2.4.4.2
24stringa di byteElemento dati CBOR codificato; vedere la Sezione 2.4.4.1
25..31(Non assegnato)(Non assegnato)
32stringa UTF-8URI; vedere la Sezione 2.4.4.3
33stringa UTF-8base64url; vedere la Sezione 2.4.4.3
34stringa UTF-8base64; vedere la Sezione 2.4.4.3
35stringa UTF-8Espressione regolare; vedere la Sezione 2.4.4.3
36stringa UTF-8Messaggio MIME; vedere la Sezione 2.4.4.3
37..55798(Non assegnato)(Non assegnato)
55799multiploCBOR autodescrittivo; vedere la Sezione 2.4.5
55800+(Non assegnato)(Non assegnato)

Tabella 3: Valori per i tag

2.4.1. Data e ora​

Il valore di tag 0 è per le stringhe di data/ora che seguono il formato standard descritto in [RFC3339], come perfezionato dalla Sezione 3.3 di [RFC4287].

Il valore di tag 1 è per la rappresentazione numerica dei secondi relativi a 1970-01-01T00:00Z nel tempo UTC. (Per i valori non negativi che la Portable Operating System Interface (POSIX) definisce, il numero di secondi è contato allo stesso modo dei "secondi dall'epoca" di POSIX [TIME_T].) L'elemento etichettato può essere un intero positivo o negativo (tipi principali 0 e 1), o un numero in virgola mobile (tipo principale 7 con informazioni aggiuntive 25, 26 o 27). Si noti che il numero può essere negativo (tempo precedente a 1970-01-01T00:00Z) e, se è un numero in virgola mobile, indicare secondi frazionari.

2.4.2. Bignum​

I bignum sono interi che non rientrano nelle rappresentazioni intere di base fornite dai tipi principali 0 e 1. Sono codificati come un elemento dati stringa di byte, che viene interpretato come un intero senza segno n nell'ordine dei byte di rete. Per il valore di tag 2, il valore del bignum è n. Per il valore di tag 3, il valore del bignum è -1 - n. I decoder che comprendono questi tag MUST essere in grado di decodificare bignum che hanno zeri iniziali.

Ad esempio, il numero 18446744073709551616 (2**64) è rappresentato come 0b110_00010 (tipo principale 6, tag 2), seguito da 0b010_01001 (tipo principale 2, lunghezza 9), seguito da 0x010000000000000000 (un byte 0x01 e otto byte 0x00). In esadecimale:

C2 -- Tag 2 29 -- Byte string of length 9 010000000000000000 -- Bytes content

2.4.3. Frazioni decimali e bigfloat​

Le frazioni decimali combinano una mantissa intera con un fattore di scala in base 10. Sono particolarmente utili se un'applicazione necessita della rappresentazione esatta di una frazione decimale come 1.1, poiché non esiste una rappresentazione esatta per molte frazioni decimali nel virgola mobile binario.

I bigfloat combinano una mantissa intera con un fattore di scala in base 2. Sono valori in virgola mobile binari che possono superare l'intervallo o la precisione dei tre formati IEEE 754 supportati da CBOR (Sezione 2.3). I bigfloat possono anche essere usati da applicazioni vincolate che necessitano di una capacità di base di virgola mobile binario senza la necessità di supportare IEEE 754.

Una frazione decimale o un bigfloat è rappresentato come un array etichettato che contiene esattamente due numeri interi: un esponente e e una mantissa m. Le frazioni decimali (tag 4) usano esponenti in base 10; il valore di un elemento dati frazione decimale è m*(10e). I bigfloat (tag 5) usano esponenti in base 2; il valore di un elemento dati bigfloat è m*(2e). L'esponente e MUST essere rappresentato in un intero di tipo principale 0 o 1, mentre la mantissa può anche essere un bignum (Sezione 2.4.2).

Un esempio di frazione decimale è che il numero 273.15 potrebbe essere rappresentato come 0b110_00100 (tipo principale 6 per il tag, informazioni aggiuntive 4 per il tipo di tag), seguito da 0b100_00010 (tipo principale 4 per l'array, informazioni aggiuntive 2 per la lunghezza dell'array), seguito da 0b001_00001 (tipo principale 1 per il primo intero, informazioni aggiuntive 1 per il valore di -2), seguito da 0b000_11001 (tipo principale 0 per il secondo intero, informazioni aggiuntive 25 per un valore di due byte), seguito da 0b0110101010110011 (27315 in due byte). In esadecimale:

C4 -- Tag 4 82 -- Array of length 2 21 -- -2 19 6ab3 -- 27315

Un esempio di bigfloat è che il numero 1.5 potrebbe essere rappresentato come 0b110_00101 (tipo principale 6 per il tag, informazioni aggiuntive 5 per il tipo di tag), seguito da 0b100_00010 (tipo principale 4 per l'array, informazioni aggiuntive 2 per la lunghezza dell'array), seguito da 0b001_00000 (tipo principale 1 per il primo intero, informazioni aggiuntive 0 per il valore di -1), seguito da 0b000_00011 (tipo principale 0 per il secondo intero, informazioni aggiuntive 3 per il valore di 3). In esadecimale:

C5 -- Tag 5 82 -- Array of length 2 20 -- -1 03 -- 3

Le frazioni decimali e i bigfloat non forniscono alcuna rappresentazione di Infinity, -Infinity o NaN; se questi sono necessari al posto di una frazione decimale o di un bigfloat, si possono usare le rappresentazioni IEEE 754 a mezza precisione della Sezione 2.3. Per le applicazioni vincolate, dove c'è una scelta tra rappresentare un numero specifico come intero e come frazione decimale o bigfloat (ad esempio quando l'esponente è piccolo e non negativo), vi è un'aspettativa di qualità dell'implementazione che venga usata direttamente la rappresentazione intera.

2.4.4. Suggerimenti sul contenuto​

I tag in questa sezione sono suggerimenti sul contenuto che potrebbero essere usati da processori CBOR generici.

2.4.4.1. Elemento dati CBOR codificato​

A volte è utile trasportare un elemento dati CBOR incorporato che non è destinato a essere decodificato immediatamente nel momento in cui l'elemento dati che lo contiene viene analizzato. Il tag 24 (elemento dati CBOR) può essere usato per etichettare la stringa di byte incorporata come un elemento dati codificato nel formato CBOR.

2.4.4.2. Codifica successiva prevista per i convertitori da CBOR a JSON​

I tag da 21 a 23 indicano che una stringa di byte potrebbe richiedere una codifica specifica quando si interopera con una rappresentazione basata su testo. Questi tag sono utili quando un encoder sa che i dati della stringa di byte che sta scrivendo saranno probabilmente convertiti in seguito in un particolare uso basato su JSON. Tale uso specifica che alcune stringhe sono codificate come base64, base64url e così via. L'encoder usa stringhe di byte invece di eseguire la codifica stessa per ridurre la dimensione del messaggio, per ridurre la dimensione del codice dell'encoder, o entrambe. L'encoder non sa se il convertitore sarà generico, e quindi vuole dire quella che ritiene essere la modalità corretta di convertire stringhe binarie in JSON.

L'elemento dati etichettato può essere una stringa di byte o qualsiasi altro elemento dati. In quest'ultimo caso, il tag si applica a tutti gli elementi dati stringa di byte contenuti nell'elemento dati, eccetto quelli contenuti in un elemento dati annidato etichettato con una conversione prevista.

Questi tre tipi di tag suggeriscono conversioni verso tre delle codifiche dati di base definite in [RFC4648]. Per la codifica base64url, il padding non viene usato (vedere la Sezione 3.2 di RFC 4648); vale a dire, tutti i segni di uguale finali ("=") sono rimossi dalla stringa codificata in base64url. In seguito potrebbero essere definiti tag per altre codifiche dati di RFC 4648 o per altri modi di codificare dati binari nelle stringhe.

2.4.4.3. Testo codificato​

Alcune stringhe di testo contengono dati che hanno formati ampiamente usati su Internet, e talvolta tali formati possono essere validati e presentati all'applicazione in forma appropriata dal decoder. Esistono tag per alcuni di questi formati.

  • Il tag 32 è per gli URI, come definito in [RFC3986];

  • I tag 33 e 34 sono per stringhe di testo codificate in base64url e base64, come definito in [RFC4648];

  • Il tag 35 è per le espressioni regolari nella sintassi Perl Compatible Regular Expressions (PCRE) / JavaScript [ECMA262].

  • Il tag 36 è per i messaggi MIME (inclusi tutti gli header), come definito in [RFC2045];

Si noti che i tag 33 e 34 differiscono da 21 e 22 in quanto i dati sono trasportati in forma codificata in base per i primi e in forma di stringa di byte grezza per i secondi.

2.4.5. CBOR autodescrittivo​

In molte applicazioni, sarà chiaro dal contesto che CBOR viene impiegato per codificare un elemento dati. Ad esempio, un protocollo specifico potrebbe specificare l'uso di CBOR, oppure viene indicato un tipo di media che ne specifica l'uso. Tuttavia, possono esserci applicazioni in cui tali informazioni di contesto non sono disponibili, come quando i dati CBOR sono memorizzati in un file e non viene usato alcun metadato di disambiguazione. In tal caso, può essere utile avere alcune caratteristiche distintive per i dati stessi.

Il tag 55799 è definito a questo scopo. Esso non conferisce alcuna semantica speciale all'elemento dati che segue; vale a dire, la semantica di un elemento dati etichettato con il tag 55799 è esattamente identica alla semantica dell'elemento dati stesso.

La serializzazione di questo tag è 0xd9d9f7, che non risulta essere in uso come contrassegno distintivo per tipi di file usati di frequente. In particolare, non è un inizio valido di un testo Unicode in alcuna codifica Unicode se seguito da un elemento dati CBOR valido.

Ad esempio, un decoder potrebbe essere in grado di analizzare sia CBOR sia JSON. Un tale decoder dovrebbe distinguere meccanicamente i due formati. Un modo semplice per un encoder di aiutare il decoder sarebbe etichettare l'intero elemento CBOR con il tag 55799, la cui serializzazione non si troverà mai all'inizio di un testo JSON.