1. Introduction (Introduzione)
Esistono centinaia di formati standardizzati per la rappresentazione binaria di dati strutturati (noti anche come formati di serializzazione binaria, Binary Serialization Formats). Di questi, alcuni sono per specifici domini di informazione, mentre altri sono generalizzati per dati arbitrari. Nell'IETF, i formati probabilmente più noti in quest'ultima categoria sono BER e DER di ASN.1 [ASN.1].
Il formato definito qui segue alcuni obiettivi di progettazione specifici che non sono ben soddisfatti dai formati attuali. Il modello di dati sottostante (Data Model) è una versione estesa del modello di dati JSON [RFC8259]. È importante notare che questa non è una proposta di estendere la grammatica in RFC 8259 in generale, poiché ciò causerebbe una significativa incompatibilità all'indietro con i documenti JSON già distribuiti. Invece, questo documento definisce semplicemente il proprio modello di dati che parte da JSON.
L'Appendice E elenca alcuni formati binari esistenti e discute in che misura si adattino o meno agli obiettivi di progettazione della Concise Binary Object Representation (CBOR, Rappresentazione Concisa di Oggetti Binari).
Questo documento rende obsoleto [RFC7049], fornendo miglioramenti editoriali, nuovi dettagli e correzioni di errata mantenendo la piena compatibilità con il formato di scambio di RFC 7049. Non crea una nuova versione del formato.
1.1. Objectives (Obiettivi)
Gli obiettivi di CBOR, approssimativamente in ordine decrescente di importanza, sono:
-
La rappresentazione deve essere in grado di codificare senza ambiguità la maggior parte dei formati di dati comuni utilizzati negli standard Internet.
-
Deve rappresentare un insieme ragionevole di tipi di dati e strutture di base utilizzando la codifica binaria. "Ragionevole" qui è largamente influenzato dalle capacità di JSON, con l'aggiunta principale di stringhe di byte binari (Byte String). Le strutture supportate sono limitate ad array (Array) e alberi (Tree); i cicli (Loop) e i grafi a reticolo (Lattice-Style Graph) non sono supportati.
-
Non è richiesto che tutti i formati di dati siano codificati in modo univoco; cioè, è accettabile che il numero "7" possa essere codificato in più modi diversi.
-
-
Il codice per un encoder o decoder deve poter essere compatto per supportare sistemi con memoria, potenza del processore e set di istruzioni molto limitati.
-
Un encoder e un decoder devono essere implementabili con una quantità molto piccola di codice (ad esempio, in nodi vincolati di classe 1 come definiti in [RFC7228]).
-
Il formato dovrebbe utilizzare rappresentazioni di dati di macchine contemporanee (ad esempio, non richiedendo la conversione binario-decimale).
-
-
I dati devono poter essere decodificati senza una descrizione dello schema (Schema Description).
- Simile a JSON, i dati codificati dovrebbero essere auto-descrittivi (Self-Describing) in modo che possa essere scritto un decoder generico.
-
La serializzazione deve essere ragionevolmente compatta, ma la compattezza dei dati è secondaria alla compattezza del codice per l'encoder e il decoder.
- "Ragionevole" qui è delimitato da JSON come limite superiore in dimensione e dalla complessità dell'implementazione, che limita la quantità di sforzo che può essere dedicata al raggiungimento di tale compattezza. L'uso di schemi di compressione generali o manipolazioni estese di bit viola gli obiettivi di complessità.
-
Il formato deve essere applicabile sia ai nodi vincolati (Constrained Node) che alle applicazioni ad alto volume.
- Ciò significa che deve essere ragionevolmente parsimonioso nell'uso della CPU sia per la codifica che per la decodifica. Questo è rilevante sia per i nodi vincolati che per l'uso potenziale in applicazioni con un volume di dati molto elevato.
-
Il formato deve supportare tutti i tipi di dati JSON per la conversione da e verso JSON.
- Deve supportare un livello ragionevole di conversione finché i dati rappresentati rientrano nelle capacità di JSON. Deve essere possibile definire una mappatura unidirezionale verso JSON per tutti i tipi di dati.
-
Il formato deve essere estensibile e i dati estesi devono essere decodificabili dai decoder precedenti.
-
Il formato è progettato per decenni di utilizzo.
-
Il formato deve supportare una forma di estensibilità che consenta il fallback in modo che un decoder che non comprende un'estensione possa comunque decodificare il messaggio.
-
Il formato deve poter essere esteso in futuro da standard IETF successivi.
-
1.2. Terminology (Terminologia)
Le parole chiave "MUST" (DEVE), "MUST NOT" (NON DEVE), "REQUIRED" (RICHIESTO), "SHALL" (DOVRÀ), "SHALL NOT" (NON DOVRÀ), "SHOULD" (DOVREBBE), "SHOULD NOT" (NON DOVREBBE), "RECOMMENDED" (RACCOMANDATO), "NOT RECOMMENDED" (NON RACCOMANDATO), "MAY" (PUÒ) e "OPTIONAL" (OPZIONALE) in questo documento devono essere interpretate come descritto in BCP 14 [RFC2119] [RFC8174] quando, e solo quando, appaiono in tutte maiuscole, come mostrato qui.
Il termine "byte" (byte) è usato nel suo senso ormai consueto come sinonimo di "octet" (ottetto). Tutti i valori multi-byte sono codificati in ordine di byte di rete (Network Byte Order) (cioè, byte più significativo per primo, noto anche come "big-endian").
Questa specifica fa uso della seguente terminologia:
Data item (elemento di dati): Un singolo pezzo di dati CBOR. La struttura di un elemento di dati può contenere zero, uno o più elementi di dati annidati. Il termine è usato sia per l'elemento di dati nel formato di rappresentazione che per l'idea astratta che può essere derivata da esso da un decoder; il primo può essere indirizzato specificamente utilizzando il termine "encoded data item" (elemento di dati codificato).
Decoder (decoder): Un processo che decodifica un elemento di dati CBOR codificato ben formato e lo rende disponibile a un'applicazione. Formalmente parlando, un decoder contiene un parser per scomporre l'input utilizzando le regole sintattiche di CBOR, nonché un processore semantico (Semantic Processor) per preparare i dati in una forma adatta all'applicazione.
Encoder (encoder): Un processo che genera il formato di rappresentazione (ben formato) di un elemento di dati CBOR dalle informazioni dell'applicazione.
Data Stream (flusso di dati): Una sequenza di zero o più elementi di dati, non ulteriormente assemblati in un elemento di dati contenente più grande (vedere [RFC8742] per un'applicazione). Gli elementi di dati indipendenti che compongono un flusso di dati sono talvolta chiamati anche "top-level data items" (elementi di dati di livello superiore).
Well-formed (ben formato): Un elemento di dati che segue la struttura sintattica di CBOR. Un elemento di dati ben formato utilizza i byte iniziali e le stringhe di byte e/o elementi di dati che sono implicati dai loro valori come definito in CBOR e non include dati estranei successivi. I decoder CBOR per definizione restituiscono solo contenuti da elementi di dati ben formati.
Valid (valido): Un elemento di dati che è ben formato e segue anche le restrizioni semantiche che si applicano agli elementi di dati CBOR (Sezione 5.3).
Expected (atteso): Oltre al suo normale significato inglese, il termine "expected" è usato per descrivere requisiti oltre la validità CBOR che un'applicazione ha sui suoi dati di input. Well-formed (elaborabile), valid (verificato da un decoder generico di controllo della validità) ed expected (verificato dall'applicazione) formano una gerarchia di livelli di accettabilità.
Stream decoder (decoder di flusso): Un processo che decodifica un flusso di dati e rende disponibile ciascuno degli elementi di dati nella sequenza a un'applicazione man mano che vengono ricevuti.
I termini e i concetti per i valori in virgola mobile come Infinity, NaN (non un numero, Not a Number), zero negativo (Negative Zero) e subnormali (Subnormal) sono definiti in [IEEE754].
Dove vengono spiegati l'aritmetica dei bit o i tipi di dati, questo documento utilizza la notazione familiare dal linguaggio di programmazione C [C], tranne che ".." denota un intervallo che include entrambe le estremità date, e la notazione in apice denota l'esponenziazione. Ad esempio, 2 alla potenza di 64 è notato: 2^(64). Nella versione in testo semplice di questa specifica, la notazione in apice non è disponibile e quindi è resa da una notazione sostitutiva. Tale notazione non è ottimizzata per questa RFC; è sfortunatamente ambigua con l'or esclusivo di C (che viene utilizzato solo nelle appendici, che a loro volta non usano l'esponenziazione) e richiede circospezione dal lettore della versione in testo semplice.
Gli esempi e lo pseudocodice presuppongono che gli interi con segno utilizzino la rappresentazione in complemento a due e che gli spostamenti a destra degli interi con segno eseguano l'estensione del segno; queste ipotesi sono anche specificate nelle Sezioni 6.8.1 (basic.fundamental) e 7.6.7 (expr.shift) della versione 2020 di C++ (attualmente disponibile come bozza finale, [Cplusplus20]).
Simile alla notazione "0x" per i numeri esadecimali, i numeri in notazione binaria sono preceduti da "0b". I trattini bassi possono essere aggiunti a un numero esclusivamente per la leggibilità, quindi 0b00100001 (0x21) potrebbe essere scritto 0b001_00001 per enfatizzare l'interpretazione desiderata dei bit nel byte; in questo caso, è diviso in tre bit e cinque bit. Gli elementi di dati CBOR codificati sono talvolta dati nella notazione "0x" o "0b"; questi valori sono prima interpretati come numeri come in C e poi interpretati come stringhe di byte in ordine di byte di rete, inclusi eventuali byte zero iniziali espressi nella notazione.
Le parole possono essere in corsivo per enfasi; nella forma di testo semplice di questa specifica, questo è indicato circondando le parole con caratteri di sottolineatura. Il testo letterale (ad esempio, nomi da un linguaggio di programmazione) può essere impostato in tipo "monospaziato"; nel testo semplice, questo è approssimato in modo alquanto ambiguo circondando il testo con virgolette doppie (che mantengono anche il loro significato abituale).