RFC 8949 CBOR 2020年12月
Bormann & Hoffman 標準化過程 [ページ]
ストリーム:
インターネット技術タスクフォース(IETF)
RFC:
8949
STD:
94
廃止対象:
7049
カテゴリ:
標準化過程
公開日:
ISSN:
2070-1721
著者:
C. Bormann
Universität Bremen TZI
P. Hoffman
ICANN

RFC 8949

簡潔なバイナリオブジェクト表現(CBOR)

概要

簡潔なバイナリオブジェクト表現(CBOR)はデータ形式であり、その設計 目標には、 極めて小さなコードサイズ、かなり小さなメッセージサイズ、および バージョンネゴシエーションを 必要としない拡張性の可能性が含まれる。これらの設計目標により、ASN.1 や MessagePack などの以前の バイナリ シリアライゼーションとは異なるものになっている。

本文書は RFC 7049 を廃止し、編集上の改善、新たな 詳細、および正誤表の修正を提供しつつ、 RFC 7049 の交換形式との完全な互換性を維持する。これは、この形式の 新しいバージョンを作成するものではない。

本文書の位置づけ

これはインターネット標準化過程の文書である。

本文書はインターネット技術タスクフォース(IETF)の成果物である。 これは IETF コミュニティの総意を表す。公開レビューを 受けており、インターネット技術運営グループ(IESG)により 公開が承認されている。インターネット標準に関する詳細情報は RFC 7841 のセクション 2 で入手できる。

本文書の現在の状態、正誤表、および本文書へのフィードバックの 提供方法に関する情報は、 https://www.rfc-editor.org/info/rfc8949 で入手できる。

目次

1. 序論

構造化データのバイナリ表現 (バイナリシリアライゼーション形式としても知られる)には、何百もの標準化された形式がある。 そのうち、特定の情報領域向けのものもあれば、 任意のデータ向けに汎用化されたものもある。IETF では、後者のカテゴリでおそらく最もよく知られている 形式は ASN.1 の BER および DER [ASN.1] である。

ここで定義される形式は、現在の形式では十分に満たされていない いくつかの具体的な設計目標に従う。基礎となるデータモデルは、 JSON データモデル [RFC8259] の拡張版である。ここで 注意すべき重要な点は、これは RFC 8259 の文法を一般に 拡張する提案ではないということである。そうすると、すでに配備されている JSON 文書との大きな後方互換性の問題を引き起こすためである。 その代わりに、本文書は JSON から出発する独自のデータモデルを 単に定義する。

付録 E は既存のいくつかのバイナリ形式を挙げ、 それらが簡潔なバイナリオブジェクト表現(CBOR)の設計目的に どの程度合うか、または合わないかを論じている。

本文書は [RFC7049] を廃止し、 RFC 7049 の交換形式との完全な互換性を保ちながら、 編集上の改善、新たな詳細、および正誤表の修正を提供する。 これはこの形式の新しいバージョンを作成するものではない。

1.1. 目的

CBOR の目的は、おおむね重要度の高い順に、 次のとおりである。

  1. 表現は、インターネット標準で使われるほとんどの一般的な データ形式を曖昧さなく符号化できなければならない。

    • バイナリ符号化を用いて、合理的な基本 データ型および構造の集合を表現しなければならない。 ここでの「合理的」は、JSON の能力に大きく影響されており、 主な追加点はバイナリバイト文字列である。 サポートされる構造は配列およびツリーに限られ、 ループおよび束風のグラフはサポートされない。
    • すべてのデータ形式が一意に 符号化されることは要求されない。すなわち、数値「7」が 複数の異なる方法で符号化されることは許容される。
  2. 非常に限られたメモリ、処理能力、および命令セットを持つ システムをサポートするため、エンコーダまたはデコーダのコードは コンパクトにできなければならない。

    • エンコーダおよびデコーダは、非常に 少量のコードで実装可能である必要がある(たとえば、 [RFC7228] で定義されるクラス 1 制約ノードにおいて)。
    • この形式は、現代の機械における データ表現を使用するべきである(たとえば、二進数から十進数への変換を 要求しない)。
  3. データは、スキーマ記述なしで復号できなければならない。

    • JSON と同様に、符号化データは 汎用デコーダを記述できるよう、自己記述的であるべきである。
  4. シリアライゼーションは十分にコンパクトでなければならないが、 データのコンパクトさはエンコーダおよびデコーダのコードの コンパクトさに次ぐものである。

    • ここでの「合理的」は、サイズにおいては JSON を上限とし、実装の複雑さによって制限される。 そのため、そのコンパクトさを達成するために投入できる労力の量も 制限される。汎用圧縮方式または広範なビット操作を使用することは、 複雑さに関する目標に反する。
  5. この形式は、制約ノードと大量処理アプリケーションの 両方に適用可能でなければならない。

    • これは、符号化および復号の両方において CPU 使用量が十分に節約される必要があることを意味する。 これは、制約ノードと、非常に大量のデータを扱う可能性のある アプリケーションの両方に関係する。
  6. この形式は、JSON との相互変換のために すべての JSON データ型をサポートしなければならない。

    • 表現されるデータが JSON の能力の範囲内にある限り、 合理的なレベルの変換をサポートしなければならない。 すべてのデータ型について、JSON へ向かう単方向マッピングを 定義できなければならない。
  7. この形式は拡張可能でなければならず、拡張されたデータは 以前のデコーダでも復号可能でなければならない。

    • この形式は、何十年にもわたる使用を想定して 設計されている。
    • この形式は、拡張を理解しないデコーダでも メッセージを復号できるよう、フォールバックを可能にする 形式の拡張性をサポートしなければならない。
    • この形式は、将来の IETF 標準によって 将来拡張できなければならない。

1.2. 用語

本文書におけるキーワード「MUST」、「MUST NOT」、 「REQUIRED」、「SHALL」、「SHALL NOT」、「SHOULD」、「SHOULD NOT」、 「RECOMMENDED」、「NOT RECOMMENDED」、 「MAY」、および「OPTIONAL」は、 ここに示すようにすべて大文字で現れる場合に限り、 BCP 14 [RFC2119] [RFC8174] に記述されるとおりに 解釈される。

用語「byte」は、現在慣用的な意味で「octet」の同義語として 使用される。すべてのマルチバイト値はネットワークバイト順 (すなわち、最上位バイトが先、別名「ビッグエンディアン」)で符号化される。

本仕様は、次の用語を使用する。

データ項目:
CBOR データの単一の断片。データ項目の構造には、 0 個、1 個、またはそれ以上の入れ子になったデータ項目を含めることができる。 この用語は、表現形式におけるデータ項目と、デコーダによってそこから 導出できる抽象的な考えの両方に用いられる。前者は 「符号化データ項目」という用語を用いることで具体的に指すことができる。
デコーダ:
整形式の符号化 CBOR データ項目を復号し、アプリケーションが利用できるようにする プロセス。形式的にいえば、デコーダは、CBOR の構文規則を用いて 入力を分解するパーサと、アプリケーションに適した形式で データを準備するセマンティックプロセッサを含む。
エンコーダ:
アプリケーション情報から CBOR データ項目の(整形式の)表現形式を 生成するプロセス。
データストリーム:
0 個以上のデータ項目のシーケンスであり、より大きな包含データ項目として さらに組み立てられていないもの(一つの応用例については [RFC8742] を参照)。 データストリームを構成する独立したデータ項目は、 「トップレベルデータ項目」とも呼ばれることがある。
整形式:
CBOR の構文構造に従うデータ項目。整形式のデータ項目は、 CBOR で定義されるとおり、その値によって暗示される初期バイトおよび バイト文字列またはデータ項目を使用し、後続する余分なデータを含まない。 CBOR デコーダは、定義上、整形式のデータ項目からの内容のみを返す。
妥当:
整形式であり、かつ CBOR データ項目に適用されるセマンティックな 制限にも従うデータ項目(セクション 5.3)。
想定:
通常の英語の意味に加えて、用語「expected」は、アプリケーションが 入力データに対して持つ、CBOR の妥当性を超える要件を 記述するために使用される。整形式(そもそも処理可能)、 妥当(妥当性検査を行う汎用デコーダによって検査される)、 および想定(アプリケーションによって検査される)は、 受け入れ可能性の階層を形成する。
ストリームデコーダ:
データストリームを復号し、シーケンス内の各データ項目を 受信されるごとにアプリケーションが利用できるようにするプロセス。

Infinity、NaN(数値ではない)、負のゼロ、および非正規数などの 浮動小数点値に関する用語および概念は、[IEEE754] で定義される。

ビット演算またはデータ型を説明する場合、本文書は プログラミング言語 C [C] でなじみのある表記を使用する。ただし、 「..」は与えられた両端を含む範囲を表し、上付き表記は べき乗を表す。たとえば、2 の 64 乗は 264 と表記される。 本仕様のプレーンテキスト版では、上付き表記は利用できないため、 代替表記で表示される。その表記はこの RFC に最適化されておらず、 残念ながら C の排他的論理和(これは付録でのみ使用され、 付録ではべき乗は使用されない)と曖昧であり、 プレーンテキスト版の読者に注意深さを要求する。

例および擬似コードは、 符号付き整数が 2 の補数表現を使用し、符号付き整数の右シフトが 符号拡張を行うことを仮定している。これらの仮定は、 C++ の 2020 年版(現在は最終ドラフト [Cplusplus20] として利用可能)の セクション 6.8.1(basic.fundamental)および 7.6.7(expr.shift)にも 規定されている。

16 進数の「0x」表記と同様に、 2 進表記の数値には「0b」が接頭される。アンダースコアは 読みやすさのためだけに数値に追加できるため、 0b00100001(0x21)は、バイト中のビットの望ましい解釈を 強調するために 0b001_00001 と書かれることがある。この場合、 3 ビットと 5 ビットに分割される。符号化された CBOR データ 項目は、「0x」または「0b」表記で与えられることがある。 これらの値は最初に C と同様に数値として解釈され、その後、 表記に含まれる先頭のゼロバイトも含めて、ネットワークバイト順の バイト文字列として解釈される。

語は強調のために イタリック体 にされることがある。 本仕様のプレーンテキスト形式では、これは単語をアンダースコア文字で 囲むことによって示される。逐語テキスト(例: プログラミング言語由来の名前)は monospace 体で組まれることがある。プレーンテキストでは、 これは多少曖昧ではあるが、テキストを二重引用符で囲むことによって近似される (二重引用符は通常の意味も保持する)。

2. CBOR データモデル

CBOR は、その汎用データモデルについて明示的である。 これは、CBOR で表現できるすべてのデータ項目の集合を定義する。 その基本汎用データモデルは、「単純値」およびタグの登録によって 拡張可能である。アプリケーションはその結果得られる拡張汎用 データモデルの部分集合を作成して、それぞれの特定データモデルを 構築できる。

汎用データモデル内のデータ項目を表現できる環境では、 汎用 CBOR エンコーダおよびデコーダを実装できる (通常、環境内に自然な表現をまだ持たないデータ項目について、 追加の実装データ型を定義することを伴う)。 汎用エンコーダおよびデコーダを提供できることは、CBOR の明示的な設計目標である。 ただし、多くのアプリケーションは独自のアプリケーション固有の エンコーダまたはデコーダを提供する。

セクション 3 で定義される 基本(未拡張)汎用データモデルにおいて、データ項目は次のいずれかである。

このモデルでは、同じ数値を持つ場合でも、整数値と浮動小数点値は 異なることに注意する。

また、シリアライゼーションの変種は汎用データモデルのレベルでは 可視ではないことにも注意する。この意図的な不可視性には、符号化された 浮動小数点値のバイト数も含まれる。また、整数の符号化、 テキストまたはバイト文字列の長さの符号化、配列中の要素数または マップ中のペア数の符号化、あるいはタグ番号の符号化など、 「引数」(セクション 3 参照)の符号化の選択も含まれる。

2.1. 拡張汎用データ モデル

この基本汎用データモデルは、本文書において、 次のような多数の単純値およびタグ番号の登録によって拡張されている。

  • falsetruenull、および undefined (20..23 によって識別される単純値、セクション 3.3
  • 上記よりも大きな範囲および精度を持つ 整数値および浮動小数点値 (タグ番号 2 から 5、セクション 3.4
  • RFC 3339 で定義される、ある時点または 日時文字列などのアプリケーションデータ型 (タグ番号 1 および 0、セクション 3.4

拡張汎用データモデルの追加要素は、CBOR 用に作成された IANA レジストリを通じて定義できる(かつ実際に定義されている)。 そのような拡張が汎用エンコーダまたはデコーダに知られていない場合でも、 その拡張を使用するデータ項目は、基本汎用データモデル内で、 すなわち汎用単純値または汎用タグとして、アプリケーションインタフェースにおいて 表現することにより、アプリケーションとの間で受け渡しできる。

言い換えれば、基本汎用データモデルは本文書で定義されるとおり 安定している一方で、拡張汎用データモデルは新しい単純値または タグ番号の登録によって拡大するが、決して縮小しない。

汎用エンコーダおよびデコーダが、falsetrue、 および nullundefined は意図的に省かれている)を それぞれのプログラミング環境に適した形式で表現できることには強い期待があるが、 タグによって作成されるデータモデル拡張の実装は真に任意であり、 実装品質の問題である。

2.2. 特定データモデル

CBOR ベースのプロトコルの特定データモデルは、通常、 拡張汎用データモデルの部分集合を取り、その部分集合および その構成要素内のデータ項目にアプリケーションセマンティクスを割り当てる。 そのような特定データモデルを文書化し、データ項目の型を指定する場合は、 CBOR 表現の側面(「メジャー型 1」、「メジャー型 4」)を参照するのではなく、 汎用データモデル名(「負の整数」、「配列」)によって型を 識別することが望ましい。

特定データモデルは、マップキーおよびエンコーダの自由度のために、 (異なる型の値を含む)値の等価性も指定できる。 たとえば、汎用データモデルでは、妥当なマップは 00.0 の両方をキーとして持つことが MAY であり、 エンコーダは 0.0 を整数 (メジャー型 0、セクション 3.1)として 符号化してはならない(MUST NOT)。 しかし、ある特定データモデルが、整数値を表す浮動小数点表現と 整数表現を等価であると宣言した場合、単一のマップで 00.0 の両方をマップキーとして使用することは、 異なるメジャー型で符号化されていても重複とみなされ、 したがって無効となる。また、エンコーダは、符号化バイトを節約するためなどに、 整数値の浮動小数点数を整数として、またはその逆に符号化できる。

3. CBOR 符号化の仕様

CBOR データ項目(セクション 2)は、 本セクションで説明される整形式の符号化データ項目を運ぶバイト文字列へ 符号化され、またはそこから復号される。この符号化は、初期バイトによって索引付けされた 付録 B表 7 に 要約されている。エンコーダは、整形式の符号化データ項目のみを生成しなければならない (MUST)。デコーダは、整形式の符号化 CBOR データ項目ではない入力に 遭遇した場合、復号データ項目を返してはならない(MUST NOT) (これは、損傷した符号化 CBOR データ項目から何らかの情報を利用可能にする可能性のある 診断ツールおよび回復ツールの有用性を損なうものではない)。

各符号化データ項目の初期バイトには、メジャー型に関する情報 (上位 3 ビット、セクション 3.1 で説明)と 追加情報(下位 5 ビット)の両方が含まれる。 いくつかの例外を除き、追加情報の値は、符号なし整数「引数」を どのように読み込むかを記述する。

24 未満:
引数の値は追加情報の値である。
24、25、26、または 27:
引数の値は、それぞれ後続する 1、2、4、または 8 バイトに ネットワークバイト順で保持される。メジャー型 7 かつ 追加情報値 25、26、27 の場合、これらのバイトは 整数引数としてではなく、浮動小数点値として使用される (セクション 3.3 を参照)。
28、29、30:
これらの値は CBOR 形式への将来の追加のために予約されている。 現在のバージョンの CBOR では、その符号化項目は整形式ではない。
31:
引数値は導出されない。 メジャー型が 0、1、または 6 の場合、符号化項目は 整形式ではない。メジャー型 2 から 5 では、項目の長さは 不定であり、メジャー型 7 では、そのバイトはデータ項目を 構成せず、不定長項目を終了する。これらはすべて セクション 3.2 で説明される。

初期バイトおよび引数を構成するために消費される追加バイトは、 まとめてデータ項目の ヘッド と呼ばれる。

この引数の意味はメジャー型に依存する。 たとえば、メジャー型 0 では引数はデータ項目そのものの値であり (メジャー型 1 では、データ項目の値は引数から計算される)、 メジャー型 2 および 3 では、後続する文字列データのバイト単位の長さを与え、 メジャー型 4 および 5 では、囲まれるデータ項目の数を決定するために使用される。

符号化されたバイトシーケンスがデータ項目の終わりより前で 終了した場合、その項目は整形式ではない。最外側の符号化項目が 復号された後にも、符号化されたバイトシーケンスにまだバイトが残っている場合、 その符号化は単一の整形式 CBOR 項目ではない。 アプリケーションによっては、デコーダはその符号化を整形式ではないものとして扱うか、 あるいは残りのバイトの開始位置をアプリケーションに識別するだけにすることができる。

CBOR デコーダ実装は、初期バイトの 256 個すべての定義済み値を持つ ジャンプテーブル(表 7)に基づくことができる。 制約された実装のデコーダは、よりコンパクトなコードのために、 初期バイトおよび後続バイトの構造を代わりに使用できる (これがどのように見えるかの大まかな印象については 付録 C を参照)。

3.1. メジャー型

以下は、メジャー型と、その型に関連付けられる追加情報および その他のバイトの一覧である。

メジャー型 0:
範囲 0..264-1 の符号なし整数(両端を含む)。 符号化項目の値は引数そのものである。たとえば、 整数 10 は 1 バイト 0b000_01010(メジャー型 0、 追加情報 10)として表される。整数 500 は 0b000_11001 (メジャー型 0、追加情報 25)の後に、10 進数で 500 を表す 2 バイト 0x01f4 が続く。
メジャー型 1:
範囲 -264..-1 の負の整数(両端を含む)。 項目の値は -1 から引数を引いたものである。たとえば、整数 -500 は 0b001_11001(メジャー型 1、追加情報 25)の後に、 10 進数で 499 を表す 2 バイト 0x01f3 が続く。
メジャー型 2:
バイト文字列。文字列中のバイト数は引数に等しい。 たとえば、長さ 5 のバイト文字列は、初期バイト 0b010_00101(メジャー型 2、長さに対する追加情報 5)を持ち、 その後に 5 バイトのバイナリ内容が続く。長さ 500 のバイト文字列は、 0b010_11001(メジャー型 2、2 バイト長を示す追加情報 25)の 3 個の初期バイトを持ち、その後に長さ 500 を表す 2 バイト 0x01f4 が続き、さらに 500 バイトのバイナリ内容が続く。
メジャー型 3:
UTF-8 [RFC3629] として符号化された テキスト文字列(セクション 2)。 文字列中のバイト数は引数に等しい。 無効な UTF-8 シーケンスを含む文字列は、整形式ではあるが無効である (セクション 1.2)。 この型は、人間が読めるテキストを解釈または表示する必要があるシステムのために提供され、 非構造化バイトと、指定されたレパートリ(Unicode のもの)および符号化(UTF-8)を持つ テキストとの区別を可能にする。JSON などの形式とは対照的に、この型の Unicode 文字は 決してエスケープされない。したがって、改行文字(U+000A)は、文字列内では常に バイト 0x0a として表され、バイト 0x5c6e(文字「\」と「n」)や 0x5c7530303061(文字「\」、「u」、「0」、「0」、「0」、「a」)としては 決して表されない。
メジャー型 4:
データ項目の配列。他の形式では、配列はリスト、シーケンス、 またはタプルとも呼ばれる(ただし「CBOR sequence」は少し異なるもの [RFC8742] である)。 引数は配列中のデータ項目の数である。配列中の項目は、 すべて同じ型である必要はない。たとえば、任意の型の項目を 10 個含む配列は、初期バイト 0b100_01010 (メジャー型 4、長さに対する追加情報 10)を持ち、 その後に残りの 10 個の項目が続く。
メジャー型 5:
データ項目のペアのマップ。マップは、テーブル、辞書、ハッシュ、 または(JSON における)オブジェクトとも呼ばれる。マップは、 データ項目のペアから構成され、各ペアはキーと、 その直後に続く値からなる。引数は、マップ内のデータ項目の ペア の数である。たとえば、9 個のペアを含むマップは、 初期バイト 0b101_01001(メジャー型 5、ペア数に対する追加情報 9)を持ち、 その後に残りの 18 個の項目が続く。最初の項目は最初のキー、 2 番目の項目は最初の値、3 番目の項目は 2 番目のキー、という具合である。 マップ内の項目はペアで現れるため、その総数は常に偶数である。 奇数個の項目を含むマップ(最後のキーデータ項目の後に値データが存在しない)は 整形式ではない。重複キーを持つマップは整形式である場合があるが、 妥当ではないため、不確定な復号を引き起こす。 セクション 5.6 も参照。
メジャー型 6:
タグ番号(範囲 0..264-1 の整数)が引数であり、 その包含データ項目(タグ内容)がヘッドに続く単一の 符号化データ項目であるタグ付きデータ項目(「タグ」)。 セクション 3.4 を参照。
メジャー型 7:
浮動小数点数および単純値、ならびに「break」停止コード。 セクション 3.3 を参照。

これら 8 つのメジャー型により、データ項目の初期バイトに対して 取り得る 256 個の値のうち、どれが使用されるかを示す単純な表 (表 7)が得られる。

メジャー型 6 および 7 では、取り得る値の多くが 将来の仕様のために予約されている。これらの値に関する詳細は セクション 9 を参照。

表 1 は、 さしあたり セクション 3.2 を無視して、 CBOR によって定義されるメジャー型を要約する。この表の数値 N は 引数を表す。

表 1: CBOR メジャー型の 定長使用の概要(N = 引数)
メジャー型 意味 内容
0 符号なし整数 N -
1 負の整数 -1-N -
2 バイト文字列 N バイト
3 テキスト文字列 N バイト(UTF-8 テキスト)
4 配列 N 個のデータ項目(要素)
5 マップ 2N 個のデータ項目(キー/値ペア)
6 番号 N のタグ 1 個のデータ項目
7 単純値/浮動小数点 -

3.2. 一部のメジャー型に対する 不定長

4 種類の CBOR 項目(配列、マップ、バイト文字列、および テキスト文字列)は、追加情報値 31 を使用して不定長で符号化できる。 これは、配列またはマップ内の項目数、あるいは文字列の総長が わかる前に、その項目の符号化を開始する必要がある場合に有用である。 (データ項目のすべてが分かる前に送信を開始できる能力は、 そのデータ項目内で「ストリーミング」と呼ばれることが多い。)

不定長の配列およびマップは、不定長の文字列 (バイト文字列およびテキスト文字列)とは異なる方法で扱われる。

3.2.1. 「break」停止 コード

「break」停止コードは、メジャー型 7 および追加情報値 31 (0b111_11111)で符号化される。これはそれ自体データ項目ではなく、 不定長項目を閉じるための構文上の機能にすぎない。

不定長の文字列、配列、またはマップの直内以外で、 データ項目が期待される場所に「break」停止コードが現れた場合 -- たとえば、定長配列またはマップの直内に現れた場合 -- その包含項目は整形式ではない。

3.2.2. 不定長配列およびマップ

不定長配列およびマップは、それぞれのメジャー型に 追加情報値 31 を用い、その後に配列では 0 個以上の項目の任意長シーケンス、 マップではキー/値ペアの任意長シーケンスが続き、最後に「break」 停止コード(セクション 3.2.1)が続くことで表現される。言い換えれば、不定長の 配列およびマップは、追加情報値 31 で始まり、「break」停止コードで終わる点を除き、 他の配列およびマップと同一に見える。

マップ内でキーの後に、そのキーの値の代わりとして 「break」停止コードが現れた場合、そのマップは整形式ではない。

不定長の配列またはマップ項目を入れ子にすることに対する 制限はない。「break」は単一の項目だけを終了するため、 入れ子になった不定長項目には、不定長項目を開始する型バイトの数と ちょうど同じ数の「break」停止コードが必要である。

たとえば、エンコーダが抽象配列 [1, [2, 3], [4, 5]] を 表現したいとする。定長符号化は 0x8301820203820405 となる。

83        -- 長さ 3 の配列
   01     -- 1
   82     -- 長さ 2 の配列
      02  -- 2
      03  -- 3
   82     -- 長さ 2 の配列
      04  -- 4
      05  -- 5

不定長符号化は、このデータ項目内で符号化される 3 つの配列それぞれに、必要に応じて独立に適用でき、 次のような表現につながる。

0x9f018202039f0405ffff
9F        -- 不定長配列の開始
   01     -- 1
   82     -- 長さ 2 の配列
      02  -- 2
      03  -- 3
   9F     -- 不定長配列の開始
      04  -- 4
      05  -- 5
      FF  -- 「break」(内側の配列)
   FF     -- 「break」(外側の配列)
0x9f01820203820405ff
9F        -- 不定長配列の開始
   01     -- 1
   82     -- 長さ 2 の配列
      02  -- 2
      03  -- 3
   82     -- 長さ 2 の配列
      04  -- 4
      05  -- 5
   FF     -- 「break」
0x83018202039f0405ff
83        -- 長さ 3 の配列
   01     -- 1
   82     -- 長さ 2 の配列
      02  -- 2
      03  -- 3
   9F     -- 不定長配列の開始
      04  -- 4
      05  -- 5
      FF  -- 「break」
0x83019f0203ff820405
83        -- 長さ 3 の配列
   01     -- 1
   9F     -- 不定長配列の開始
      02  -- 2
      03  -- 3
      FF  -- 「break」
   82     -- 長さ 2 の配列
      04  -- 4
      05  -- 5

不定長マップの例(たまたま 2 つのキー/値ペアを持つ)は、 次のようになる。

0xbf6346756ef563416d7421ff
BF           -- 不定長マップの開始
   63        -- 最初のキー、長さ 3 の UTF-8 文字列
      46756e --   "Fun"
   F5        -- 最初の値、true
   63        -- 2 番目のキー、長さ 3 の UTF-8 文字列
      416d74 --   "Amt"
   21        -- 2 番目の値、-2
   FF        -- 「break」

3.2.3. 不定長バイト文字列およびテキスト文字列

不定長文字列は、バイト文字列またはテキスト文字列の メジャー型と追加情報値 31 を含むバイトで表現され、その後に 指定された型の定長文字列(「チャンク」)が 0 個以上続き、 最後に「break」停止コード(セクション 3.2.1)で 終了する。不定長文字列によって表現されるデータ項目は、 これらのチャンクの連結である。チャンクが存在しない場合、 そのデータ項目は指定された型の空文字列である。長さゼロのチャンクは、 特に有用ではないが、許可される。

不定長文字列インジケータ(0b010_11111 または 0b011_11111)と 「break」停止コードの間にある任意の項目が、同じメジャー型の 定長文字列項目でない場合、その文字列は整形式ではない。

この設計では、不定長文字列をチャンクとして 不定長文字列に入れ子にすることは許可していない。 もし許可されるなら、デコーダ実装は入れ子レベルのスタック、 または少なくともカウントを保持する必要がある。エンコーダ側では不要である。 なぜなら、内側の不定長文字列はチャンクから構成されるため、 それらを外側の不定長文字列に直接置くことができるからである。

不定長テキスト文字列内のいずれかの定長テキスト文字列が 無効である場合、その不定長テキスト文字列は無効である。 これは、単一の Unicode コードポイント(スカラー値)の UTF-8 バイトを チャンク間に分散できないことを意味する点に注意する。 テキスト文字列の新しいチャンクは、コードポイント境界でのみ開始できる。

たとえば、次のバイトからなる符号化データ項目を想定する。

0b010_11111 0b010_00100 0xaabbccdd 0b010_00011 0xeeff99 0b111_11111
5F              -- 不定長バイト文字列の開始
   44           -- 長さ 4 のバイト文字列
      aabbccdd  -- バイト内容
   43           -- 長さ 3 のバイト文字列
      eeff99    -- バイト内容
   FF           -- 「break」

復号後、これは 7 バイトの単一のバイト文字列 0xaabbccddeeff99 となる。

3.2.4. メジャー型における 不定長使用の概要

表 2 は、 CBOR によって定義されるメジャー型について、 不定長符号化(追加情報を 31 に設定)で使用される場合を要約する。

表 2: CBOR メジャー型の 不定長使用の概要(追加情報 = 31)
メジャー型 意味 「break」停止コードまでに 囲まれるもの
0 (整形式ではない) -
1 (整形式ではない) -
2 バイト文字列 定長バイト文字列
3 テキスト文字列 定長テキスト文字列
4 配列 データ項目(要素)
5 マップ データ項目(キー/値ペア)
6 (整形式ではない) -
7 「break」停止コード -

3.3. 浮動小数点数 および内容を持たない値

メジャー型 7 は、浮動小数点数と、 内容を必要としない「単純値」という 2 種類のデータのためのものである。 初期バイト内の 5 ビットの追加情報の各値は、 表 3 で定義されるように、 それぞれ独自の意味を持つ。整数用のメジャー型と同様に、 このメジャー型の項目は内容データを運ばない。すべての情報は 初期バイト(ヘッド)にある。

表 3: メジャー型 7 における 追加情報の値
5 ビット値 セマンティクス
0..23 単純値(値 0..23)
24 単純値(後続バイト内の値 32..255)
25 IEEE 754 半精度浮動小数点数(16 ビットが続く)
26 IEEE 754 単精度浮動小数点数(32 ビットが続く)
27 IEEE 754 倍精度浮動小数点数(64 ビットが続く)
28-30 予約済み、本文書では整形式ではない
31 不定長項目のための「break」停止コード (セクション 3.2.1

他のすべてのメジャー型と同様に、5 ビット値 24 は 1 バイトの拡張を示す。これは単純値を表すために 追加バイトが後続する。(混乱を最小限にするため、値 32 から 255 のみが使用される。)これにより初期バイトの構造は維持される。 すなわち、他のメジャー型と同様に、これらの長さは常に 最初のバイト内の追加情報に依存する。表 4 は、 単純値に割り当てられている数値および利用可能な数値を示す。

表 4: 単純値
セマンティクス
0..19 (未割り当て)
20 false
21 true
22 null
23 undefined
24..31 (予約済み)
32..255 (未割り当て)

エンコーダは、0xf8(メジャー型 7、追加情報 24)で始まり、 0x20(10 進数 32)未満のバイトが続く 2 バイトシーケンスを 発行してはならない(MUST NOT)。そのようなシーケンスは 整形式ではない。(これは、エンコーダが falsetruenull、または undefined を 2 バイトシーケンスで 符号化できず、これらの 1 バイト変種のみが整形式であることを意味する。 より一般的にいえば、各単純値は単一の表現変種のみを持つ。)

5 ビット値 25、26、および 27 は、16 ビット、32 ビット、 および 64 ビットの IEEE 754 バイナリ浮動小数点値 [IEEE754] のためのものである。 これらの浮動小数点値は、適切なサイズの追加バイト内に符号化される。 (16 ビット浮動小数点数に関する情報については 付録 D を参照。)

3.4. 項目へのタグ付け

CBOR では、タグ番号 によって一意に識別される 追加のセマンティクスを与えるために、データ項目をタグで囲むことができる。 タグはメジャー型 6 であり、その引数(セクション 3)は タグ番号を示し、単一の包含データ項目である タグ内容 を含む。 (タグがその内容にさらなる構造を要求する場合、その構造は 囲まれたデータ項目によって提供される。) 本文書では、タグ番号とタグ内容の両方からなるデータ項目全体に タグ という用語を用いる。タグ内容はタグ付けされている データ項目である。

たとえば、長さ 12 のバイト文字列が、 それが符号なし bignumセクション 3.4.3)であることを示すために 番号 2 のタグで印付けされるとする。 符号化データ項目は、バイト 0b110_00010(メジャー型 6、 タグ番号に対する追加情報 2)で始まり、その後に符号化されたタグ内容、 すなわち 0b010_01100(メジャー型 2、長さに対する追加情報 12)と 12 バイトの bignum が続く。

拡張汎用データモデルでは、タグ番号の定義は、 そのタグ番号で伝達される追加セマンティクスを記述する。 これらのセマンティクスには、いくつかのタグ付きデータ項目と 他のデータ項目との等価性が含まれる場合があり、 その中には基本汎用データモデルで表現できるものもある。 たとえば、0xc24101、すなわちタグ内容が単一バイト 0x01 の バイト文字列である bignum は、整数 1 と等価であり、 それは 0x01、0x1801、または 0x190001 としても符号化できる。 タグ定義は、汎用エンコーダに推奨される優先シリアライゼーション (セクション 4.1)を指定できる。 これはタグを用いる表現よりも、基本汎用データモデル表現を 優先する場合がある。

タグ定義は通常、そのようなタグに対してどの入れ子データ項目が 妥当であるかを定義する。タグ定義は、本文書で定義されるタグがそうであるように、 その内容を非常に具体的な構文構造に制限することもあれば、 その内容をよりセマンティックに定義することもある。 後者の例は、タグ 40 および 1040 が配列を表現する複数の方法を 受け入れる方法である [RFC8746]

慣例として、多くのタグはタグ内容として null または undefined 値を受け入れない。その代わりに、 null または undefined 値はタグ全体の代わりに 使用できるという期待がある。セクション 3.4.2 は、 アプリケーションプロトコルおよびプラットフォーム型へのマッピングにおける この慣例の扱いについて、特定のタグに関するさらなる考慮事項を提供する。

デコーダはすべてのタグ番号のタグを理解する必要はなく、 特定の CBOR データ項目を作成する実装と、そのストリームを復号する実装が データフロー内の各項目のセマンティックな意味を知っているアプリケーションでは、 タグの価値はほとんどない場合がある。本仕様におけるタグの主な目的は、 日付などの共通データ型を定義することである。副次的な目的は、 CBOR データ項目を別の形式に変換する必要が予見される場合に、 項目の内容に関するヒントを要求する変換ヒントを提供することである。 タグのセマンティクスを理解することはデコーダにとって任意であり、 デコーダはタグの追加セマンティクスを解釈することなく、タグ番号と タグ内容の両方をアプリケーションに提示するだけでもよい。

タグは、それが囲むデータ項目にセマンティクスを適用する。 タグは入れ子にできる。タグ A がタグ B を囲み、タグ B がデータ項目 C を囲む場合、 タグ A は、データ項目 C にタグ B を適用した結果に適用される。

IANA は、セクション 9.2 で説明されるタグ番号のレジストリを管理する。 表 5 は、[RFC7049] で 定義され、本セクションの残りで定義されるタグ番号の一覧を提供する。 (タグ番号 35 も [RFC7049] で定義された。 このタグ番号に関する議論は セクション 3.4.5.3 に続く。) [RFC7049] の発行以来、多くの他のタグ番号が 定義されていることに注意する。完全な一覧については、 セクション 9.2 で説明されるレジストリを参照。

表 5: RFC 7049 で定義されたタグ番号
タグ データ項目 セマンティクス
0 テキスト文字列 標準日時文字列。セクション 3.4.1 を参照
1 整数または浮動小数点数 エポックに基づく日時。セクション 3.4.2 を参照
2 バイト文字列 符号なし bignum。セクション 3.4.3 を参照
3 バイト文字列 負の bignum。セクション 3.4.3 を参照
4 配列 十進小数。セクション 3.4.4 を参照
5 配列 bigfloat。セクション 3.4.4 を参照
21 (任意) base64url 符号化への想定変換。 セクション 3.4.5.2 を参照
22 (任意) base64 符号化への想定変換。 セクション 3.4.5.2 を参照
23 (任意) base16 符号化への想定変換。 セクション 3.4.5.2 を参照
24 バイト文字列 符号化された CBOR データ項目。 セクション 3.4.5.1 を参照
32 テキスト文字列 URI。セクション 3.4.5.3 を参照
33 テキスト文字列 base64url。セクション 3.4.5.3 を参照
34 テキスト文字列 base64。セクション 3.4.5.3 を参照
36 テキスト文字列 MIME メッセージ。セクション 3.4.5.3 を参照
55799 (任意) 自己記述型 CBOR。セクション 3.4.6 を参照

概念的には、タグは(デ)シリアライゼーション時ではなく、 汎用データモデルにおいて解釈される。少数のタグ (現時点ではタグ番号 25 およびタグ番号 29 [IANA.cbor-tags])は、 (デ)シリアライゼーション時の処理を必要とする可能性のある セマンティクスで登録されている。すなわち、デコーダはデータ項目が CBOR データ項目へ符号化される正確なシーケンスを認識する必要があり、 エンコーダはそれを制御できる必要がある。 これは、これらのタグを任意の汎用 CBOR エンコーダ/デコーダの上に 実装できないことを意味する(そのようなエンコーダ/デコーダは、 データモデルレベルでマップ内のエントリのシリアライゼーション順序を 反映しない可能性があり、その逆も同様である)。したがって、それらの実装は 通常、汎用エンコーダ/デコーダに統合する必要がある。 この性質を持つ新しいタグの定義は NOT RECOMMENDED である。

IANA は、タグ番号 65535、4294967295、および 18446744073709551615(16 ビット、32 ビット、および 64 ビットにおける バイナリの全ビット 1)を割り当てた。 これらは、特定のタグの存在またはタグの不存在のいずれかを示す 単一整数データ構造を求める実装者にとって便利なものとして使用できる。 その割り当ては、[CBOR-TAGS] のセクション 10 で説明されている。 これらのタグは、実際の CBOR データ項目に現れることを意図していない。 実装は、そのような出現をエラーとして標示してもよい (MAY)。

プロトコルは、タグ番号 0 および 1 を用いて時点を表す データ項目を、タグ番号 2 および 3 を用いて任意サイズの整数を、 タグ番号 4 および 5 を用いて任意サイズおよび任意精度の 浮動小数点値を利用することで、汎用データモデル (セクション 2)を拡張できる。

3.4.1. 標準 日時文字列

タグ番号 0 は、[RFC3339]date-time 生成規則で 記述され、[RFC4287] のセクション 3.3 によって精緻化された 標準形式のテキスト文字列を含み、そこで記述される時点を表す。 別の型の入れ子項目、または [RFC4287] で 記述される形式に一致しないテキスト文字列は無効である。

3.4.2. エポックに基づく 日時

タグ番号 1 は、UTC 時間の 1970-01-01T00:00Z から 表現される民用時の時点までの秒数を数える数値を含む。

タグ内容は、符号なしまたは負の整数(メジャー型 0 および 1)、または浮動小数点数(追加情報 25、26、または 27 を持つ メジャー型 7)でなければならない(MUST)。 その他の包含型は無効である。

非負の値(メジャー型 0 および非負の浮動小数点数)は、 1970-01-01T00:00Z UTC 以降の時刻値を表し、 POSIX [TIME_T] に従って解釈される。 (POSIX 時間は「UNIX エポック時間」としても知られる。) うるう秒は POSIX 時間によって特別に処理され、その結果、 10 年に数回 1 秒の不連続が生じる。 2106 年初頭を超える時刻の表現を必要とするアプリケーションは、 タグ内容に対する 64 ビット整数のサポートを省くことができない点に注意する。

負の値(メジャー型 1 および負の浮動小数点数)は、 1970-01-01T00:00Z より前の UTC 秒数時間について普遍的な標準が 存在しないため、アプリケーション要件によって決定されるように解釈される (これは特に、国の暦における不連続より前の時点に当てはまる)。 同じことは非有限値にも当てはまる。

小数秒を示すために、タグ番号 1 内で整数値の代わりに 浮動小数点値を使用できる。これは一般に binary64 のサポートを必要とする点に 注意する。binary16 および binary32 は、1970 年初頭の周辺の短い期間でしか 非ゼロの小数秒を提供しないためである。 タグ番号 1 のサポートを必要とするアプリケーションは、 タグ内容を整数(または浮動小数点値)のみに制限できる。

日時用のプラットフォーム型には null または undefined 値が含まれる場合があり、これはアプリケーションプロトコルレベルでも 望ましい場合があることに注意する。 非有限のタグ内容値(たとえば、未定義の日時値に対する NaN や、 設定されていない有効期限に対する Infinity)を持つタグ番号 1 の値を 発行することは、この処理方法として明白に見えるかもしれないが、 タグなしの null または undefined を使用すれば、 非有限値の使用を避け、より短い符号化となる。 アプリケーションプロトコル設計者は、これらのケースを検討し、 それらを扱うための明確な指針を含めることが推奨される。

3.4.3. Bignums

タグ番号 2 および 3 を使用するプロトコルは、 任意サイズの整数を表す「bignums」により、汎用データモデル (セクション 2)を拡張する。 基本汎用データモデルでは、bignum 値は同じモデルの整数と等しくないが、 このタグ定義によって作成される拡張汎用データモデルは数値に基づく 等価性を定義し、優先シリアライゼーション(セクション 4.1)は 基本整数としても表現できる bignum を決して使用しない(下記参照)。

Bignum はバイト文字列データ項目として符号化され、 これはネットワークバイト順の符号なし整数 n として解釈される。 他の型の包含項目は無効である。タグ番号 2 では、bignum の値は n である。 タグ番号 3 では、bignum の値は -1 - n である。 バイト文字列の優先シリアライゼーションは、先頭のゼロを省くことである (これは n = 0 の優先シリアライゼーションが空のバイト文字列であることを意味するが、 下記を参照)。 これらのタグを理解するデコーダは、先頭のゼロを持つ bignum も復号できなければならない (MUST)。 メジャー型 0 または 1 を使用して表現できる整数の優先シリアライゼーションは、 それを bignum としてではなく、この方法で符号化することである (これは、優先シリアライゼーションを使用する場合、空文字列が bignum に決して 現れないことを意味する)。 数値を符号化するために、基本整数の代わりに bignum 表現を選ぶ非優先の選択は、 必要以上に長い基本整数表現(たとえば 0x00 に対する 0x1800)の選択と同様に、 アプリケーションセマンティクスを持つことを意図していない点に注意する。

たとえば、数値 18446744073709551616(264)は、 0b110_00010(メジャー型 6、タグ番号 2)の後に、 0b010_01001(メジャー型 2、長さ 9)が続き、 さらに 0x010000000000000000(1 バイト 0x01 と 8 バイトの 0x00)が 続くものとして表現される。16 進数では次のとおりである。

C2                        -- タグ 2
   49                     -- 長さ 9 のバイト文字列
      010000000000000000  -- バイト内容

3.4.4. 十進小数 および Bigfloats

タグ番号 4 を使用するプロトコルは、m*(10e) の形の 任意長の十進小数を表すデータ項目で汎用データモデルを拡張する。 タグ番号 5 を使用するプロトコルは、m*(2e) の形の 任意長の二進小数を表すデータ項目で汎用データモデルを拡張する。 bignum と同様に、異なる型の値は汎用データモデルでは等しくない。

十進小数は、整数の仮数と 10 を基数とする倍率を組み合わせる。 これは、1.1 などの十進小数の正確な表現をアプリケーションが 必要とする場合に最も有用である。多くの十進小数には、 二進浮動小数点表現における正確な表現がないためである。

「Bigfloats」は、整数の仮数と 2 を基数とする倍率を 組み合わせる。これらは、CBOR がサポートする 3 つの IEEE 754 形式 (セクション 3.3)の範囲または精度を 超えることができる二進浮動小数点値である。Bigfloats は、IEEE 754 を サポートする必要なしに、何らかの基本的な二進浮動小数点能力を必要とする 制約アプリケーションでも使用できる。

十進小数または bigfloat は、2 つの整数値、 すなわち指数 e と仮数 m を正確に含むタグ付き配列として表現される。 十進小数(タグ番号 4)は 10 を基数とする指数を使用し、 十進小数データ項目の値は m*(10e) である。 Bigfloat(タグ番号 5)は 2 を基数とする指数を使用し、 bigfloat データ項目の値は m*(2e) である。 指数 e はメジャー型 0 または 1 の整数で表現されなければならず (MUST)、一方で仮数は bignum (セクション 3.4.3)であってもよい。 他の構造を持つ包含項目は無効である。

十進小数の例として、数値 273.15 の表現は、 0b110_00100(タグのメジャー型 6、タグ番号に対する追加情報 4)の後に、 0b100_00010(配列のメジャー型 4、配列の長さに対する追加情報 2)が続き、 その後に 0b001_00001(最初の整数のメジャー型 1、値 -2 に対する追加情報 1)が続き、 さらに 0b000_11001(2 番目の整数のメジャー型 0、2 バイト値に対する追加情報 25)が続き、 最後に 0b0110101010110011(2 バイトの 27315)が続く。16 進数では次のとおりである。

C4             -- タグ 4
   82          -- 長さ 2 の配列
      21       -- -2
      19 6ab3  -- 27315

bigfloat の例として、数値 1.5 の表現は、 0b110_00101(タグのメジャー型 6、タグ番号に対する追加情報 5)の後に、 0b100_00010(配列のメジャー型 4、配列の長さに対する追加情報 2)が続き、 その後に 0b001_00000(最初の整数のメジャー型 1、値 -1 に対する追加情報 0)が続き、 さらに 0b000_00011(2 番目の整数のメジャー型 0、値 3 に対する追加情報 3)が 続く。16 進数では次のとおりである。

C5             -- タグ 5
   82          -- 長さ 2 の配列
      20       -- -1
      03       -- 3

十進小数および bigfloat は、Infinity、-Infinity、 または NaN の表現を提供しない。これらが十進小数または bigfloat の代わりに 必要な場合、セクション 3.3 の IEEE 754 半精度表現を使用できる。

3.4.5. 内容ヒント

本セクションのタグは、汎用 CBOR プロセッサによって 使用される可能性のある内容ヒントのためのものである。 これらの内容ヒントは汎用データモデルを拡張しない。

3.4.5.1. 符号化された CBOR データ項目

囲むデータ項目が復号される時点で 直ちに復号されることを意図していない埋め込み CBOR データ項目を 運ぶことが有益な場合がある。タグ番号 24(CBOR データ項目)は、 埋め込まれたバイト文字列を CBOR 形式で符号化された単一のデータ項目として タグ付けするために使用できる。バイト文字列でない包含項目は無効である。 包含されたバイト文字列は、それが整形式の CBOR データ項目を符号化していれば 妥当である。復号された CBOR 項目の妥当性検査はタグ妥当性には要求されない (ただし、特別なオプションとして汎用デコーダによって提供されてもよい)。

3.4.5.2. CBOR から JSON への変換器に対する後続の想定符号化

タグ番号 21 から 23 は、テキストベース表現との相互運用時に、 バイト文字列が特定の符号化を必要とする可能性があることを示す。 これらのタグは、エンコーダが、書き込んでいるバイト文字列データが 後で特定の JSON ベースの使用法へ変換される可能性が高いことを 知っている場合に有用である。その使用法では、一部の文字列が base64、base64url などとして符号化されることを指定する。 エンコーダは、メッセージサイズ、エンコーダのコードサイズ、またはその両方を 削減するために、自身で符号化を行う代わりにバイト文字列を使用する。 エンコーダは、変換器が汎用であるかどうかを知らないため、 バイナリ文字列を JSON に変換する適切な方法であると考えるものを 示したい。

タグ付けされるデータ項目は、バイト文字列でも、 その他の任意のデータ項目でもよい。後者の場合、タグは、 想定変換を持つ入れ子データ項目によって含まれるものを除き、 そのデータ項目に含まれるすべてのバイト文字列データ項目に適用される。

これら 3 つのタグ番号は、[RFC4648] で定義される 3 つの基本データ符号化への変換を示唆する。 タグ番号 21 は、base64url 符号化 ([RFC4648] のセクション 5)への変換を示唆する。 ここではパディングは使用されない ([RFC4648] のセクション 3.2 を参照)。 すなわち、符号化文字列から末尾の等号(「=」)はすべて取り除かれる。 タグ番号 22 は、RFC 4648 で定義されるパディング付きの 古典的な base64 符号化 ([RFC4648] のセクション 4)への変換を示唆する。 base64url と base64 の両方について、パディングビットはゼロに設定され ([RFC4648] のセクション 3.5 を参照)、 代替符号化への変換はバイト文字列の内容に対して実行される (すなわち、改行、空白、またはその他の追加文字を加えない)。 タグ番号 23 は、大文字のアルファベットを用いた base16(hex)符号化 ([RFC4648] のセクション 8)への変換を示唆する。 3 つすべてのタグ番号について、空のバイト文字列の符号化は 空のテキスト文字列であることに注意する。

3.4.5.3. 符号化されたテキスト

一部のテキスト文字列は、インターネットで広く使用される形式の データを保持し、時にはそれらの形式をデコーダが検証して、 適切な形式でアプリケーションに提示できることがある。 これらの形式の一部にはタグがある。

  • タグ番号 32 は、 [RFC3986] で 定義される URI のためのものである。テキスト文字列が URI-reference 生成規則に一致しない場合、その文字列は 無効である。
  • タグ番号 33 および 34 は、それぞれ [RFC4648] で定義される base64url 符号化テキスト文字列および base64 符号化テキスト 文字列のためのものである。次のいずれかが該当する場合、

    • 符号化テキスト文字列が 非アルファベット文字を含む、または 4 文字の最後のブロックに 1 個のアルファベット文字しか含まない (アルファベットは、タグ番号 33 については [RFC4648] のセクション 5、 タグ番号 34 については [RFC4648] のセクション 4 によって 定義される)、または
    • 2 文字または 3 文字のブロックにおけるパディングビットが 0 でない、または
    • base64 符号化が 誤った数のパディング文字を持つ、または
    • base64url 符号化が パディング文字を持つ場合、

    その文字列は無効である。

  • タグ番号 36 は、 [RFC2045] で定義される MIME メッセージ(すべてのヘッダーを含む)のためのものである。 妥当な MIME メッセージでないテキスト文字列は無効である。 (このタグでは、妥当性検査は汎用デコーダにとって特に負担が大きい場合があり、 したがって提供されないことがある。多くの MIME メッセージは一般的な バイナリデータであり、したがってテキスト文字列で表現できないことに注意する。 [IANA.cbor-tags] は、 タグ番号 36 に似ているが、タグ内容としてバイト文字列を使用する タグ番号 257 の登録を一覧している。)

タグ番号 33 および 34 は、前者ではデータが 基数符号化された形式で運ばれるのに対し、後者では生のバイト文字列形式で 運ばれる点で、21 および 22 と異なることに注意する。

[RFC7049] は、 Perl Compatible Regular Expressions(PCRE/PCRE2)形式 [PCRE] または JavaScript 正規表現構文 [ECMA262] の正規表現に対する タグ番号 35 も定義した。 これらの正規表現仕様における技術水準はその後進歩しており、 継続的に進歩しているため、本仕様は参照を更新しようとはしない。 その代わり、このタグは、使用する特定の正規表現変種を 帯域外で指定するアプリケーションのために (場合によっては PCRE と ECMA262 の両方の定義済み共通部分集合に 使用を制限することで)、[RFC7049] で登録されたとおり利用可能なままである。 本仕様は [RFC7049] を超えて タグ妥当性を明確化するため、[RFC7049] で このタグが開かれた方法で定義されたことにより、任意の包含文字列値は CBOR タグレベルで妥当である必要がある(しかしアプリケーションレベルでは 「想定」されない場合がある)ことに注意する。

3.4.6. 自己記述型 CBOR

多くのアプリケーションでは、CBOR がデータ項目の符号化に 使用されていることは文脈から明らかである。たとえば、特定のプロトコルが CBOR の使用を指定しているか、その使用を指定するメディア型が示されている場合である。 しかし、曖昧さを解消するメタデータを持たないファイルに CBOR データが保存される場合など、 そのような文脈情報が利用できないアプリケーションも存在し得る。 ここでは、データ自体に何らかの識別特性を持たせることが役立つ場合がある。

タグ番号 55799 はこの目的のために定義されており、 アプリケーションによって指定されるように、保存された符号化 CBOR データ項目の 先頭で使用するためのものである。 これは、それが囲むデータ項目に特別なセマンティクスを与えない。 すなわち、タグ番号 55799 に囲まれたタグ内容のセマンティクスは、 そのタグ内容自体のセマンティクスと完全に同一である。

このタグのヘッドのシリアライゼーションは 0xd9d9f7 であり、 頻繁に使用されるいずれのファイル型の識別マークとしても 使用されているようには見えない。特に、0xd9d9f7 は、妥当な CBOR データ項目が 後続する場合、いずれの Unicode 符号化においても Unicode テキストの 妥当な開始ではない。

たとえば、あるデコーダが CBOR と JSON の両方を 復号できるとする。そのようなデコーダは、2 つの形式を機械的に 区別する必要がある。エンコーダがデコーダを助ける簡単な方法は、 CBOR 項目全体をタグ番号 55799 でタグ付けすることである。 そのシリアライゼーションは、JSON テキストの先頭には決して見つからない。

4. シリアライゼーションに関する考慮事項

4.1. 優先 シリアライゼーション

データモデルレベルの一部の値について、CBOR は複数の シリアライゼーションを提供する。 多くのアプリケーションでは、エンコーダが常に 優先シリアライゼーション(優先符号化)を選択することが望ましい。しかし、現在の仕様は、 この選好を強制する負担をエンコーダまたはデコーダのいずれにも課さない。

一部の制約されたデコーダは、非優先シリアライゼーションを復号する 能力に制限がある場合がある。たとえば、あるアプリケーションで 1_000_000_000(一十億)未満の整数だけが想定される場合、 デコーダは整数内の 64 ビット引数を復号するために必要となるコードを 省いてもよい。常に優先シリアライゼーションを使用するエンコーダ (「優先エンコーダ」)は、このアプリケーションで出現し得る数値について、 このデコーダと相互運用する。一般に、優先エンコーダは、 たとえば常に 64 ビット整数を使用するものよりも、より普遍的に相互運用可能であり (かつ無駄も少ない)。

同様に、制約されたエンコーダは、サポートする表現変種の 種類に制限があるため、優先シリアライゼーションを 出力しない場合がある(「変種エンコーダ」)。たとえば、制約されたエンコーダは、 短い表現が利用可能であっても、符号化する整数について 常に 32 ビット変種を使用するように設計され得る (64 ビット変種でしか表現できない整数をアプリケーションが必要としないと仮定する)。 優先シリアライゼーションのみを受け取ることに依存しない デコーダ(「変種許容デコーダ」)は、したがって、より 普遍的に相互運用可能であると言える(もっとも、優先シリアライゼーションを 受け取る場合に最適化していることは十分あり得る)。 CBOR デコーダの完全な実装は、定義上、変種を許容する。 この区別は、CBOR デコーダの制約された実装が変種エンコーダと 出会う場合にのみ関係する。

優先シリアライゼーションは、常に引数 (セクション 3)を表す最短形式を使用する。 また、符号化される値を保持する最短の 浮動小数点符号化も使用する。

浮動小数点値の優先シリアライゼーションは、その値を保持する最短の 浮動小数点符号化である。たとえば、数値 5.5 には 0xf94580、 数値 5555.5 には 0xfa45ad9c00 を用いる。NaN 値については、より短い仮数を右側にゼロ埋めすることで 元の NaN 値を再構成できる場合、より短い符号化が優先される (多くのアプリケーションでは、単一の NaN 符号化 0xf97e00 で 十分である)。

項目のシリアライゼーションが開始される時点で長さがわかっている場合は、 常に定長符号化が優先される。

4.2. 決定論的に 符号化された CBOR

一部のプロトコルでは、エンコーダが特定の 決定論的形式の CBOR のみを出力することを望む場合がある。また、それらのプロトコルは、 デコーダが入力がその決定論的形式であることを検査するようにしてもよい。 それらのプロトコルは、 「決定論的形式」とは何を意味するのか、またエンコーダおよびデコーダに 何が期待されるのかを自由に定義できる。本セクションは、 そのような決定論的形式の基礎として機能し得る制限の集合を定義する。

4.2.1. 中核となる 決定論的符号化要件

CBOR 符号化は、次の制限を満たす場合に 「中核となる決定論的符号化要件」を満たす。

  • 優先シリアライゼーションを使用しなければならない (MUST)。 特に、これは整数、メジャー型 2 から 5 の長さ、およびタグの 引数(セクション 3 を参照)が 可能な限り短くなければならないことを意味する。 たとえば次のとおりである。

    • 0 から 23 および -1 から -24 は、 メジャー型と同じバイトで表現されなければならない (MUST)。
    • 24 から 255 および -25 から -256 は、 追加の uint8_t のみで表現されなければならない (MUST)。
    • 256 から 65535 および -257 から -65536 は、 追加の uint16_t のみで表現されなければならない (MUST)。
    • 65536 から 4294967295 および -65537 から -4294967296 は、追加の uint32_t のみで表現されなければならない (MUST)。

    浮動小数点値も、その値を保持する最短形式を使用しなければならない (MUST)。たとえば、1.5 は 0xf93e00(binary16)として、 1000000.5 は 0xfa49742408(binary32)として符号化される。 (この一つの実装方法は、すべての浮動小数点数を 64 ビット浮動小数点数として開始し、 32 ビット浮動小数点数への試験変換を行うことである。結果が同じ数値であれば、 より短い形式を使用し、16 ビット浮動小数点数への試験変換でこの過程を繰り返す。 これは正の Infinity および負の Infinity に対して 16 ビット浮動小数点数を 選択する場合にも機能する。)

  • 不定長項目は現れてはならない (MUST NOT)。代わりに定長項目として符号化できる。
  • すべてのマップ内のキーは、その決定論的 符号化のバイト単位の辞書順でソートされなければならない (MUST)。たとえば、次のキーは正しくソートされている。

    1. 10、0x0a として符号化。
    2. 100、0x1864 として符号化。
    3. -1、0x20 として符号化。
    4. "z"、0x617a として符号化。
    5. "aa"、0x626161 として符号化。
    6. [100]、0x811864 として符号化。
    7. [-1]、0x8120 として符号化。
    8. false、0xf4 として符号化。

4.2.2. 追加の 決定論的符号化に関する考慮事項

CBOR タグは、決定論的符号化に対して追加の考慮事項を提示する。 CBOR ベースのプロトコルが、特定のタグの存在と不在に対して同じセマンティクスを 提供する場合(たとえば、日時位置でタグ 1 データ項目と生の数値の両方を許可し、 後者をタグ付けされているかのように扱う場合)、決定論的形式は 「最短形式」の原則に基づいて、そのタグの存在を許可しない。 たとえば、プロトコルは、URL をテキスト文字列として表現するか、 セクション 3.4.5.3 を用いて テキスト文字列を含むタグ番号 32 として表現するかを、 エンコーダに選択させるかもしれない。このプロトコルの決定論的符号化では、 タグが存在することを要求するか、存在しないことを要求する必要があり、 どちらも許すことはできない。

特定の場所で特定のセマンティクスを得るためにタグを要求する プロトコルでは、決定論的形式にもそのタグが現れる必要がある。 決定論的符号化に関する考慮事項は、タグの内容にも適用される。

プロトコルが、タグ番号 2 または 3 (セクション 3.4.3)を使用して、 絶対値が 264 以上の整数を表現できるフィールドを含む場合、 そのプロトコルの決定論的符号化は、より小さい整数もこれらのタグを使用して 表現するのか、それともメジャー型 0 および 1 を使用して表現するのかを 指定する必要がある。優先シリアライゼーションは後者の選択を使用するため、 これが推奨される。

基本浮動小数点値(セクション 3.3)で表現されるか、 タグで表現されるか(またはその両方)にかかわらず、 浮動小数点値を含むプロトコルは、その決定論的符号化に対して 追加要件を定義する必要がある場合がある。たとえば次のとおりである。

  • IEEE 浮動小数点値は正のゼロと負のゼロを 区別される値として表現できるが、アプリケーションはこれらを区別せず、 すべてのゼロ値を正の符号で表現することを決定し、負のゼロを 許可しない場合がある。 (アプリケーションはまた、64 ビット、あるいは 32 ビットの 浮動小数点値を表現する必要が決して生じないように、 浮動小数点値の精度を制限したい場合もある。)
  • プロトコルが、整数値と 浮動小数点値を交換可能であると宣言する特定のデータモデルを持つ 浮動小数点値を表現できるフィールドを含む場合、そのプロトコルの 決定論的符号化は、たとえば整数 1.0 を 0x01(符号なし整数)、 0xf93c00(binary16)、0xfa3f800000(binary32)、 または 0xfb3ff0000000000000(binary64)のいずれとして符号化するかを 指定する必要がある。このための規則例は次のとおりである。

    1. 64 ビットに収まる整数値は メジャー型 0 および 1 の値として符号化し、その他の値は、その値を正確に表す 優先(16、32、または 64 ビットのうち最小の)浮動小数点表現として 符号化する。
    2. 整数値であっても、すべての値を、 その値を正確に表す優先浮動小数点表現として符号化する、または
    3. すべての値を 64 ビット浮動小数点表現として 符号化する。

    規則 1 は整数と浮動小数点値の境界をまたぎ、規則 3 は 優先シリアライゼーションを使用しない。そのため、多くの場合、 規則 2 が良い選択となり得る。

  • NaN が許可される値であり、NaN ペイロードまたはシグナリング NaN をサポートする意図がない場合、 プロトコルは単一の表現、通常は 0xf97e00 を選ぶ必要がある。 その単純な選択が不可能な場合、NaN の扱いには特別な注意が必要となる。
  • 非正規数(与えられた IEEE 754 数値形式において、 可能な最小指数を持つ非ゼロ数)は、一部の浮動小数点実装で ゼロ出力へフラッシュされたり、ゼロ入力として扱われたりする場合がある。 プロトコルの決定論的符号化は、そのような実装を特に受け入れつつ、 他の実装には負担を課す形で、非正規数を交換から除外し、 代わりにゼロを交換することを望む場合がある。
  • 同じ数値は、異なる十進小数、 異なる bigfloat、および数値を表現するために定義され得る他のタグの下の 異なる形式によって表現できる。実装によっては、これらの形式 (または基本汎用データモデル内の形式)が等価であるかどうかを 判断することが常に実際的であるとは限らない。 数値の表現形式についてこの種の選択肢を提示するアプリケーションプロトコルは、 決定論的符号化の形式をどのように選択するかを明示する必要がある。

4.2.3. 長さ優先の マップキー順序付け

中核となる決定論的符号化要件(セクション 4.2.1)は、[RFC7049] のセクション 3.9 で示唆された順序 (そこでは「Canonical CBOR」と呼ばれる)とは異なる順序で マップキーをソートする。[RFC7049] で指定された順序との互換性を 必要とするプロトコルは、代わりに本仕様の 「長さ優先の中核となる決定論的符号化要件」の観点から指定できる。

CBOR 符号化は、中核となる決定論的符号化要件を満たすが、 すべてのマップ内のキーが次のようにソートされなければならない (MUST)点だけが異なる場合、 「長さ優先の中核となる決定論的符号化要件」を満たす。

  1. 2 つのキーの長さが異なる場合、短い方が 先に並ぶ。
  2. 2 つのキーの長さが同じ場合、(バイト単位の) 辞書順で値が小さい方が先に並ぶ。

たとえば、長さ優先の中核となる決定論的符号化要件の下では、 次のキーは正しくソートされている。

  1. 10、0x0a として符号化。
  2. -1、0x20 として符号化。
  3. false、0xf4 として符号化。
  4. 100、0x1864 として符号化。
  5. "z"、0x617a として符号化。
  6. [-1]、0x8120 として符号化。
  7. "aa"、0x626161 として符号化。
  8. [100]、0x811864 として符号化。

5. CBOR ベースのプロトコルの作成

CBOR のようなデータ形式は、形式ネゴシエーションが存在しない環境で 使用されることが多い。CBOR の具体的な設計目標の一つは、 含まれる、または仮定されるスキーマを必要としないことである。 デコーダは CBOR 項目を受け取り、他の知識なしにそれを復号できる。

もちろん、実世界の実装では、エンコーダとデコーダは CBOR データ項目内に何があるべきかについて共通の見解を持つ。 たとえば、合意された形式は「その項目は配列であり、 最初の値は UTF-8 文字列、2 番目の値は整数、以降の値は 0 個以上の浮動小数点数である」または「その項目は キーにバイト文字列を持ち、キーが 0xab01 であるペアを含む マップである」といったものかもしれない。

CBOR ベースのプロトコルは、そのデコーダが無効なデータおよび その他の予期しないデータをどのように扱うかを指定しなければならない (MUST)。CBOR ベースのプロトコルは、 任意の妥当なデータを予期しないものとして扱うと指定してもよい (MAY)。CBOR ベースのプロトコルのエンコーダは、 妥当な項目のみを生成しなければならない(MUST)。 すなわち、プロトコルは無効な項目を利用するように設計できない。 エンコーダは、それが使用されるプロトコルで必要とされるだけ多く、または少ない種類の値を 符号化できればよく、デコーダは、それが使用されるプロトコルで必要とされるだけ多く、 または少ない種類の値を理解できればよい。この制限の欠如により、 CBOR は極めて制約の厳しい環境で使用できる。

本セクションの残りでは、CBOR ベースのプロトコルを作成する際の いくつかの考慮事項について論じる。少数の例外を除き、これは助言的なものにすぎず、 BCP 14 [RFC2119] [RFC8174] に由来する用語のうち、 BCP 14 の意味で「MAY」と解釈できる語以外を明示的に除外する。 例外は、汎用およびアプリケーション固有のエンコーダとデコーダの 幅広い種類を利用しながら、CBOR ベースのプロトコルの 相互運用性を促進することを目的とする。

5.1. ストリーミング アプリケーションにおける CBOR

ストリーミングアプリケーションでは、データストリームは、 CBOR データ項目を連続して連結したシーケンスで構成される場合がある。 そのような環境では、以前のデータ項目の終端後にデータが見つかると、 デコーダは直ちに新しいデータ項目の復号を開始する。

データ項目を構成するすべてのバイトが、デコーダに直ちに 利用可能であるとは限らない。一部のデコーダは、完全なデータ項目を アプリケーションに提示できるようになるまで追加データをバッファする。 他のデコーダは、すでに復号できた入れ子データ項目や、まだ完全には到着していない バイト文字列の一部など、トップレベルデータ項目に関する部分的情報を アプリケーションに提示できる。 そのようなアプリケーションはまた、アプリケーションに提示される増分データに対して 望ましい保護が利用可能な、対応するストリーミングセキュリティ機構を 持たなければならない(MUST)。

一部のアプリケーションおよびプロトコルは、不定長符号化を 使用したくない場合があることに注意する。不定長符号化を使用すると、 エンコーダは数を数えるためにすべてのデータをまとめる必要がなくなるが、 デコーダは項目の終端を待つ間、増加するメモリ量を割り当てる必要がある。 これは一部のアプリケーションには適しているかもしれないが、 他のアプリケーションには適さない場合がある。

5.2. 汎用エンコーダおよび デコーダ

汎用 CBOR デコーダは、すべての整形式の符号化 CBOR データ項目を 復号し、データ項目をアプリケーションに提示できる。付録 C を参照。 (診断表記、セクション 8 は、 整形式の CBOR 値を人間に提示するために使用できる。)

汎用 CBOR エンコーダは、エンコーダが知らない単純値やタグを 含め、任意の整形式の値を CBOR データ項目として符号化するよう アプリケーションが指定できるアプリケーションインタフェースを提供する。

CBOR はこれらのケースを最小限にしようとするが、 すべての整形式 CBOR データが妥当であるとは限らない。 たとえば、符号化テキスト文字列 0x62c0ae は 妥当な UTF-8 を含まない([RFC3629] が 常に最短形式の使用を要求するため)ため、妥当な CBOR 項目ではない。 また、特定のタグは、たとえば bignum タグが別のタグを囲む場合や、 タグ番号 0 のインスタンスがバイト文字列を含む場合、または [RFC3339]date-time 生成規則に一致しない内容を持つテキスト文字列を含む場合などに、 違反され得るセマンティックな制約を課すことがある。 汎用エンコーダおよびデコーダが、無効なデータの処理を可能にするために アプリケーションインタフェースについて不自然な選択を行うことは要求されない。 汎用エンコーダおよびデコーダは、単純値およびタグの特定のコードポイントが エンコーダ/デコーダの作成時に登録されていない場合でも、それらを転送することが期待される (セクション 5.4)。

5.3. 項目の妥当性

整形式ではあるが無効な CBOR データ項目 (セクション 1.2)は、 CBOR データモデルにおいて、その中に符号化されたデータを解釈する際の 問題を提示する。CBOR ベースのプロトコルは複数の層で指定され得る。 下位層は、転送する CBOR データの一部のセマンティクスを処理しない。 これらの層は、処理しないデータ内の妥当性エラーに気づくことができず、 そのデータをそのまま転送しなければならない(MUST)。 無効な CBOR 項目のセマンティクスを処理する最初の層は、次の 2 つの選択肢の いずれかを選ばなければならない(MUST)。

  1. 問題のある項目をエラーマーカーに置き換え、 次の項目で続行する、または
  2. エラーを発行し、処理を完全に停止する。

CBOR ベースのプロトコルは、デコーダが遭遇する可能性のある 無効な項目の各種類について、これらの選択肢のどちらを取るかを 指定しなければならない(MUST)。

そのような問題は、CBOR の基本的妥当性レベルまたは タグの文脈(タグ妥当性)で発生する可能性がある。

5.3.1. 基本的な妥当性

基本汎用データモデルでは、2 種類の妥当性エラーが 発生し得る。

マップ内の重複キー:
汎用デコーダ(セクション 5.2)は、 ネイティブ CBOR データモデルを用いてアプリケーションにデータを 利用可能にする。そのデータモデルには、マップ (一意のキーを持つキー値対応)が含まれ、マルチマップ (複数のエントリが同じキーを持ち得るキー値対応)は含まれない。 したがって、重複キーを持つ CBOR マップ項目を受け取った汎用デコーダは、 そのキーのインスタンスが 1 つだけのマップへ復号するか、処理を完全に 停止するかもしれない。一方、「ストリーミングデコーダ」は、 それに気づくことすらできない場合がある。マップ内のキーに関するさらなる議論については、 セクション 5.6 を参照。
無効な UTF-8 文字列:
デコーダは、UTF-8 文字列(メジャー型 3)内のバイトシーケンスが 実際に妥当な UTF-8 であることを検証し、適切に反応したい場合も、 そうでない場合もある。

5.3.2. タグの妥当性

基本汎用データモデルにタグを追加することにより、 さらに 2 種類の妥当性エラーが導入される。

タグ内容に対する許容されない型:
タグ番号(セクション 3.4)は、 そのタグ内容として使用されることが想定されるデータ項目の型を指定する。 たとえば、符号なしまたは負の bignum 用のタグ番号は、 バイト文字列に付けられることが想定されている。 タグ付きデータ項目をネイティブ表現(この例ではネイティブ大整数)へ 復号するデコーダは、タグ付けされているデータ項目の型を検査することが期待される。 そのようなネイティブ表現を環境で利用できないデコーダであっても、 自身が知っているタグについては検査を行い、適切に反応できる。
タグ内容に対する許容されない値:
データ項目の型はタグの内容として許容され得るが、具体的な値が 許容されない場合がある。たとえば、「yesterday」という値は、 適切にテキスト文字列であっても、タグ 0 の内容としては受け入れられない。 通常このようなタグを等価なプラットフォーム型に取り込むデコーダは、 未知のタグ番号を持つタグを提示するのと同様の方法で、 このタグをアプリケーションに提示するかもしれない (セクション 5.4)。

5.4. 妥当性と発展

妥当性検査を行うデコーダは、妥当性エラーを持つデータ項目を 信頼できる形で検出するための労力を費やす。たとえば、そのような デコーダには、前のサブセクションに列挙された妥当性エラーのいずれかを含む CBOR データ項目についてエラーを報告する(かつデータを返さない) API が必要である。

「Concise Binary Object Representation (CBOR) Tags」レジストリ(セクション 9.2)で 定義されるタグの集合、および 「Concise Binary Object Representation (CBOR) Simple Values」 レジストリ(セクション 9.1)で定義される 単純値の集合は、汎用デコーダが理解する集合を超えて いつでも増大し得る。妥当性検査を行うデコーダは、 認識できないそのようなケースに遭遇した場合、次の 2 つのいずれかを行える。

  • エラーを報告する(かつデータを返さない)。 このケースをエラーとして扱うことは硬直化を引き起こす可能性があるため、 推奨されない点に注意する。このエラーは、それ自体としては 妥当性エラーではない。この種のエラーは、それが既知のケースであれば 妥当性検査を実行していたであろうデコーダによって発生しやすい。
  • 未知の項目(型、値、およびタグの場合は 復号されたタグ付きデータ項目)を、デコーダを呼び出したアプリケーションに 出力し、その後、そのタグ番号または単純値をデコーダが認識しなかったことを アプリケーションに示す。

後者の方法は、妥当性検査をサポートしないデコーダにも適しており、 新たに登録されたタグおよび単純値との前方互換性を、 呼び出し元アプリケーションと同時にエンコーダを更新する必要なしに提供する。 (そのためには、デコーダの API に、未知の項目をマークする能力が必要であり、 それにより呼び出し元アプリケーションはプログラムに適した方法でそれらを扱える。)

妥当性検査に必要な処理の一部には、かなりのコストがかかる場合があるため (特にマップの重複検出において)、妥当性検査のサポートは すべての CBOR デコーダに課される要件ではない。

一部のエンコーダは、エンコーダの結果として妥当な CBOR が得られるような 入力データをアプリケーションが提供することに依存する。 汎用エンコーダはまた、アプリケーションが実際に API に適合したデータを 提供しているかどうかにかかわらず、その出力を妥当な CBOR に確実に 制限する妥当性検査モードを提供したい場合がある。

5.5. 数値

CBOR ベースのプロトコルは、異なる言語環境が、表現可能な 数値の範囲および精度に対して異なる制約を課すことを考慮すべきである。 たとえば、基本的な JavaScript 数値システムはすべての数値を 浮動小数点値として扱うため、53 個を超える有効ビットを持つ整数を 復号する際に、精度が黙って失われる可能性がある。 別の例として、CBOR は整数表現の符号ビットをメジャー型内に保持するため、 ある長さの符号付き数値について、同じ長さの典型的なプラットフォーム符号付き整数表現 (8 バイト int64_t の -263..263-1)よりも 1 ビット多い範囲(たとえば 1+8 バイト整数の -264..264-1)を持つ。 数値を使用するプロトコルは、デコーダおよび受信アプリケーションにおける 自明でない数値の扱いについて期待事項を定義すべきである。

浮動小数点数を含む CBOR ベースのプロトコルは、 3 つの形式(半精度、単精度、および倍精度)のうちどれを サポートすべきかを制限できる。整数専用のアプリケーションでは、 プロトコルは浮動小数点値の使用を完全に除外したい場合がある。

コンパクトさのために設計された CBOR ベースのプロトコルは、 64 ビット整数の実装の必要を省くなどの目的で、 アプリケーションに必要な長さより長い特定の整数符号化を 除外したい場合がある。 エンコーダは、与えられた値を表現できる最もコンパクトな 整数表現を使用することが期待される。しかし、決定論的符号化を 必要としないコンパクトなアプリケーションは、アプリケーションが 与えられたサイズの整数を復号できる限り、必要以上に長い符号化 (たとえば「0」を 0b000_11001 の後に 2 バイトの 0x00 が続く形で 符号化すること)を使用する値を受け入れるべきである。 同様の考慮事項は浮動小数点値にも適用される。優先シリアライゼーションと 必要以上に長いものの両方を復号することが推奨される。

制約されたアプリケーション向けの CBOR ベースのプロトコルで、 特定の数値を整数として表現するか、十進小数または bigfloat として 表現するかの選択肢を提供するもの(指数が小さく非負である場合など)は、 整数表現が直接使用されるという実装品質上の期待を表明してもよい。

5.6. マップのキーの 指定

符号化および復号アプリケーションは、マップでどの型のキーが 使用されるかについて合意する必要がある。JSON ベースのアプリケーションと 相互運用する必要があるアプリケーションでは、キーをテキスト文字列のみに 制限することで変換が簡素化される。そうでなければ、他の CBOR 型から テキスト文字列への指定されたマッピングが必要となり、これはしばしば 実装エラーにつながる。キーが数値的な性質を持ち、キーの数値順序が アプリケーションにとって重要なアプリケーションでは、キーに数値を直接使用することが 有用である。

複数の型のキーを使用する場合、それらの型が使用される予定の 特定のプログラミング環境でどのように表現されるかを考慮すべきである。 たとえば、JavaScript Maps [ECMA262] では、 整数 1 のキーは浮動小数点 1.0 のキーと区別できない。 これは、整数キーが使用される場合、プロトコルは同じマップ内で、 値がたまたま整数である浮動小数点キーの使用を避ける必要があることを意味する。

CBOR データ項目内に入れ子になったデータ項目を、復号するとすぐに 配信するデコーダ(「ストリーミングデコーダ」)は、マップ内のキーの一意性を 確認するために必要な状態を保持しないことが多い。 同様に、包含データ項目が完全に利用可能になる前にデータ項目の符号化を 開始できるエンコーダ(「ストリーミングエンコーダ」)は、データソースが 一意性を維持することに依存することで、オーバーヘッドを大幅に減らしたい場合がある。

CBOR ベースのプロトコルは、受信アプリケーションがマップ内で 複数の同一キーを見た場合に何をするかを定義しなければならない (MUST)。プロトコル内の結果としての規則は、 CBOR データモデルを尊重しなければならない(MUST)。 すなわち、同一キーを持つエントリの特定の扱いを規定することはできない。 ただし、マップ内の同一キーが不正形式のマップを示し、デコーダがエラーで 停止しなければならないという規則を持つことはできる。 重複キーを持つエントリを示すマップを処理する場合、汎用デコーダは次のいずれかを 行うかもしれない。

  • 重複キーを持つマップを受け入れない (すなわち、マップについて妥当性を強制する。 セクション 5.4 も参照)。 これらの汎用デコーダは普遍的に有用である。 アプリケーションは、それでもアプリケーション規則に基づいて独自の重複検査を 実行する必要がある場合がある(たとえば、特定のマップのマップキー位置で 整数と浮動小数点値を同等とする場合)。
  • 重複キーを持つものを含め、 すべてのマップエントリをアプリケーションに渡す。 これには、アプリケーション規則が汎用データモデル規則と同一であっても、 アプリケーションが重複キーを処理(検査)することが必要となる。
  • 重複キーを持つ一部のエントリを失う。 たとえば、同じキーを持つエントリのうち最後(または最初)のエントリだけを 配信する。このような汎用デコーダでは、アプリケーションは同じ特定キーについて、 実行ごとに、また異なる汎用デコーダごとに異なる結果を得る可能性がある。 どの値が返されるかは、汎用デコーダの実装と、マップ内のキーの実際の順序に 基づく。特に、アプリケーションは必ずしもすべてのエントリを見るわけではないため、 自身でキーの一意性を検証できない。このような汎用デコーダは、 キーの一意性を検証する必要がある場合には使用できない可能性がある。 これらの汎用デコーダは、データソースおよび転送が常に妥当なマップを提供する 状況でのみ使用できる。これは、データソースおよび転送が攻撃され得る場合には 不可能である。

汎用デコーダは、これら 3 つの方法のうちどれを 実装しているかを文書化する必要がある。

マップの CBOR データモデルは、マップ表現内のキー/値ペアの順序に セマンティクスを帰属させることを許可しない。 したがって、CBOR ベースのプロトコルは、マップ内のキー/値ペアの順序を変更することが セマンティクスを変更すると指定してはならない(MUST NOT)。 ただし、たとえば決定論的符号化(セクション 4.2)の 要件を満たさないような順序など、一部の順序が許可されないと指定することはできる。 (マップ順序がタイミング、キャッシュ使用量、その他の潜在的なサイドチャネルに与える 二次的効果はセマンティクスの一部とはみなされないが、それ自体でプロトコルが 決定論的符号化形式を要求する十分な理由となる場合がある。)

制約デバイス向けのアプリケーションは、少数の頻繁に使用される キーを持つマップがある場合、小さい整数をキーとして使用することを検討すべきである。 たとえば、24 個以下のキーの集合は符号なし整数として 1 バイトで符号化でき、 負の整数も使用する場合は最大 48 個まで可能である。 あまり頻繁に出現しないキーには、より長い符号化を持つ整数を使用できる。

5.6.1. キーの 等価性

CBOR データ項目に適用される特定データモデルは、 マップ内に現れるキーが重複しているか、それとも別個であるかを判断するために使用される。

汎用データモデルレベルでは、数値的に等価な整数値と 浮動小数点値は互いに異なり、また各種の大きな数(タグ 2 から 5)とも 異なる。同様に、テキスト文字列は、同じバイトから構成されていても バイト文字列とは異なる。タグ付き値は、タグなし値や異なるタグ番号で タグ付けされた値とは異なる。

これらの各グループ内では、数値は数値的に等しい場合を除き 異なる(具体的には、-0.0 は 0.0 と等しい)。 マップキー等価性の目的では、NaN 値は、両方の仮数を右側で 64 ビットまでゼロ拡張した後に 同じ仮数を持つ場合に等価である。

バイト文字列およびテキスト文字列はどちらも バイト単位で比較され、配列は要素単位で比較され、 同じ数のバイト/要素を持ち、同じ位置に同じ値を持つ場合に等しい。 2 つのマップは、その順序にかかわらず同じペア集合を持つ場合に等しい。 ペアは、キーと値の両方が等しい場合に等しい。

タグ付き値は、タグ番号とタグ内容の両方が等しい場合に等しい。 (特定のタグに対する処理を提供する汎用デコーダは、 セマンティックに等価な一部の値を区別できない場合がある点に注意する。 たとえば、タグ 2 またはタグ 3 の内容に先頭のゼロが現れる場合である (セクション 3.4.3)。) 単純値は、単純に同じ値を持つ場合に等しい。 汎用データモデルでは、それ以外は何も等しくない。 単純値 2 は整数 2 と等価ではなく、配列がマップと等価になることは決してない。

セクション 2.2 で論じたように、特定データモデルは、 汎用データモデルでは異なる値を、マップキーを比較する目的で 等価にすることができる。これは、汎用デコーダが、アプリケーションによって 重複マップキーを検査する必要がある復号済みマップをアプリケーションに 配信する場合があることを意味する点に注意する (あるいは、デコーダがこのサービスをアプリケーションのために実行する プログラミングインタフェースを提供してもよい)。特定データモデルは、 この目的において汎用データモデルレベルで等しいマップキーの値を 区別できない。

5.7. 未定義値

一部の CBOR ベースのプロトコルでは、 undefined の単純値(セクション 3.3)が、 符号化上の問題を持つデータ項目の代替としてエンコーダによって使用され、 残りの包含データ項目を害なく符号化できるようにする場合がある。

6. CBOR と JSON の間でのデータ変換

本セクションは、CBOR と JSON の間で変換することについて 非規範的な助言を与える。変換器の実装は、ここにある助言のうち 望むものを使用してもよい(MAY)。

JSON テキストは文字のシーケンスであり、 符号化されたバイトシーケンスではない一方、CBOR データ項目は 文字ではなくバイトからなることは注目に値する。

6.1. CBOR から JSON への変換

CBOR のほとんどの型には、JSON に直接の類似物がある。 しかし、一部にはそれがなく、CBOR から JSON への変換器を実装する者は、 そのような場合に何をすべきかを考慮しなければならない。 次の非規範的な助言は、それらを JSON null などの 単一の代替値に変換することで扱う。

  • 整数(メジャー型 0 または 1)は JSON 数値になる。
  • 提案される符号化を指定するタグに埋め込まれていない バイト文字列(メジャー型 2)は、パディングなしの base64url で 符号化され、JSON 文字列になる。
  • UTF-8 文字列(メジャー型 3)は JSON 文字列になる。 JSON は特定の文字のエスケープを要求することに注意する ([RFC8259], セクション 7): 引用符(U+0022)、逆斜線(U+005C)、および「C0 制御文字」(U+0000 から U+001F)。その他のすべての文字は、 JSON UTF-8 文字列へ変更なしにコピーされる。
  • 配列(メジャー型 4)は JSON 配列になる。
  • マップ(メジャー型 5)は JSON オブジェクトになる。 これは、すべてのキーが UTF-8 文字列である場合に限り、 直接可能である。変換器は、他のキーも UTF-8 文字列へ変換するかもしれない (たとえば、整数をその十進表現を含む文字列へ変換することによって)。 しかし、そうするとキー衝突の危険が生じる。 また、後述の提案どおり UTF-8 文字列上のタグを無視する場合、 タグが異なっても文字列が同じであれば、これによりキー衝突が 発生することにも注意する。
  • False(メジャー型 7、追加情報 20)は JSON false になる。
  • True(メジャー型 7、追加情報 21)は JSON true になる。
  • Null(メジャー型 7、追加情報 22)は JSON null になる。
  • 浮動小数点値(メジャー型 7、追加情報 25 から 27)は、それが有限である場合(すなわち、 JSON 数値として表現できる場合)は JSON 数値になる。 値が非有限(NaN、または正または負の Infinity)である場合、 代替値によって表現される。
  • その他の単純値(メジャー型 7、 ここまででまだ論じていない任意の追加情報値)は、 代替値によって表現される。
  • bignum(メジャー型 6、タグ番号 2 または 3)は、 そのバイト文字列をパディングなしの base64url で符号化することによって 表現され、JSON 文字列になる。タグ番号 3(負の bignum)については、 base 符号化された値の前に「~」(ASCII チルダ)が挿入される。 (数値ではなくバイナリ blob へ変換するのは、JSON デコーダで起こりそうな 数値オーバーフローを防ぐためである。)
  • 符号化ヒントを持つバイト文字列 (メジャー型 6、タグ番号 21 から 23)は、そのヒントで記述されるとおりに 符号化され、JSON 文字列になる。
  • その他すべてのタグ(メジャー型 6、 その他任意のタグ番号)については、タグ内容が JSON 値として表現される。 タグ番号は無視される。
  • 不定長項目は、変換前に定長にされる。

CBOR から JSON への変換器は、相互運用性を最大化し、 JSON 出力が予測可能な結果で処理できるという信頼性を高めるために、 JSON プロファイル I-JSON [RFC7493] に 従いたい場合がある。たとえば、これは確実に表現できる整数の範囲や、 古い JSON 実装がサポートし得るトップレベル項目に影響する。

6.2. JSON から CBOR への変換

すべての JSON 値は、いったん復号されると、1 つ以上の CBOR 値へ直接対応付けられる。他のあらゆる CBOR 生成と同様に、 数値表現に関して判断を行う必要がある。提案される 変換では、次のとおりである。

  • 小数部を持たない JSON 数値(整数)は、 最短形式を選択して、整数(メジャー型 0 および 1、 場合によってはメジャー型 6、タグ番号 2 および 3)として表現される。 実装定義のしきい値より長い整数は、代わりに 浮動小数点値として表現されてもよい。 整数として表現される既定の範囲は -253+1..253-1 である (JSON の復号にしばしば使用される binary64 表現での正確な整数の範囲を 完全に活用する [RFC7493])。 CBOR ベースのプロトコル、または汎用変換器実装は、 -232..232-1 または -264..264-1 (それぞれ uint32_t または uint64_t により CBOR で利用可能な整数範囲を 完全に使用する)を選択してもよく、あるいは -231..231-1 または -263..263-1 (2 の補数の符号付き整数で一般的な範囲を使用する)を選択してもよい。 (JSON が JavaScript 実装から生成された場合、その精度はすでに 最大 53 ビットに制限されている。)
  • 小数部を持つ数値は、IEEE 754 binary64 が提供する 精度に基づいて十進から二進への変換を行い、 浮動小数点値として表現される。 JSON 数値の数学的値は、[IEEE754] のセクション 4.3.1 の roundTiesToEven 手順を用いて binary64 に変換される。 その後、CBOR で符号化する際、優先シリアライゼーションは、この変換結果を 正確に表す最短の浮動小数点表現を使用する。 たとえば、1.5 は 16 ビット浮動小数点値で表現される (ただし、すべての実装が最小形式を効率よく見つけられるわけではない)。 既定の binary64 精度を使用する代わりに、 変換精度に実装定義の制限が存在する場合があり、 それが表現される値の精度に影響する。十進表現は、 プロトコルで指定されている場合にのみ CBOR 側で使用すべきである。

CBOR は一般に JSON よりもコンパクトな符号化を提供するよう 設計されている。思い浮かぶ可能性のある一つの実装戦略は、 単一のバッファ内で JSON から CBOR への符号化をインプレースで行うことである。 この戦略では、いくつかの病的なケースを慎重に考慮する必要がある。 たとえば、エスケープがないか非常に少ない状態で表現され、255 バイトより長い (またははるかに長い)一部の文字列は、CBOR で UTF-8 文字列として 符号化されると拡大する可能性がある。同様に、一部の短い JSON の十進表現(1.1、1e9)から、いくつかの二進浮動小数点表現が 拡大を引き起こす可能性がある。これを正しく行うことは難しい場合があり、 結果として生じる脆弱性は攻撃者に悪用され得る。

7. CBOR の将来的な発展

成功したプロトコルは時間とともに発展する。新しいアイデアが現れ、 実装プラットフォームが改善され、関連プロトコルが開発されて 発展し、アプリケーションおよびプロトコルからの新しい要件が 追加される。したがって、プロトコルの発展を促進することは、 どのようなプロトコル開発においても重要な設計上の考慮事項である。

CBOR を使用するプロトコルに対して、CBOR はその発展を促進するための いくつかの有用な機構を提供する。このためのベストプラクティスは、 特に JSON ベースのプロトコルの JSON 形式開発からよく知られている。 したがって、そのようなベストプラクティスは本仕様の範囲外である。

しかし、CBOR 自体の発展を促進することは、その範囲内に十分にある。 CBOR は、CBOR ベースのプロトコル開発のための安定した基盤を提供し、 かつ発展できるように設計されている。成功したプロトコルは何十年も存続し得るため、 CBOR は何十年にもわたる使用と発展に備えて設計される必要がある。 本セクションは、CBOR の発展に関するいくつかの指針を提供する。 それは、本文書の他の部分よりも必然的に主観的である。 また、プロトコル開発の教科書になってしまわないよう、必然的に不完全でもある。

7.1. 拡張ポイント

プロトコル設計では、発展の機会が拡張ポイントの形で 含まれることが多い。たとえば、最初から完全には割り当てられていない コードポイント空間が存在し、プロトコルが、当初割り当てられた数よりも多くの コードポイントを使用し始める実装を許容し、受け入れるように設計されることがある。

必要な範囲を予測することが難しい場合があるため、 コードポイント空間のサイズ決定は難しい場合がある。プロトコル設計は、 プロトコルの意図された寿命の間にゆっくり埋められるよう、 コードポイント空間を十分に大きくすることを試みるべきである。

CBOR には 3 つの主要な拡張ポイントがある。

「simple」空間(メジャー型 7 の値):
24 個の効率的な値 (および 224 個のやや効率の低い値)のうち、割り当てられているのは 少数にすぎない。未知の単純データ項目を受け取る実装は、 その値の構造が実際に単純であるならば、それをそのように容易に 処理できる場合がある。セクション 9.1 の IANA レジストリは、このコードポイント空間の拡張性に対処する 適切な方法である。
「tag」空間(メジャー型 6 の値):
総コードポイント空間は 豊富であり、そのごく一部だけが割り当てられている。 しかし、これらすべてのコードポイントが同じように効率的であるわけではない。 最初の 24 個は単一の(「1+0」)バイトだけを消費し、 その半分はすでに割り当てられている。次の 232 個の値は 2(「1+1」)バイトだけを消費し、すでにほぼ 4 分の 1 が割り当てられている。 これらの部分空間は、さらに数十年持続するよう、いくらかの管理を必要とする。 未知のタグ番号を受け取る実装は、囲まれたタグ内容だけを処理するか、 好ましくは、タグ内容を包む未知のタグ番号としてタグを処理することを 選択できる。セクション 9.2 の IANA レジストリは、 このコードポイント空間の拡張性に対処する適切な方法である。
「additional information」空間:
未知の追加情報値を受け取る実装には、 復号を続行する方法がないため、この空間でコードポイントを割り当てることは、 単に拡張ポイントを行使することを大きく超えた大きな一歩である。 また、残されたコードポイントも非常に少ない。 セクション 7.2 も参照。

7.2. 追加情報空間の 管理

人間の心は、何かを整然とさせるために、認識された小さな隙間を 埋めようと引き寄せられることがある。追加情報値のコードポイント空間に残された隙間は、 そこにあるというだけで、新しいアイデアを引き寄せるものになると予想される。

現在の仕様は、追加情報コードポイント空間を IANA レジストリで 管理しない。その代わり、この空間からの割り当ては、 本仕様を更新することによってのみ行える。

n >= 24 の追加情報値については、追加データのサイズは通常 2n-24 バイトである。したがって、追加情報値 28 および 29 は、 それらをプロトコルに追加する必要が生じた場合に備えて、 128 ビットおよび 256 ビット量の候補と見なすべきである。 追加情報値 30 は、一般割り当てに利用可能な唯一の追加情報値となるため、 現在の仕様の更新を通じて割り当てる前に、それを割り当てる非常に正当な理由が あるべきである。

8. 診断表記

CBOR はバイナリ交換形式である。文書化およびデバッグを容易にし、 特にデバッグで協力するエンティティ間の通信を容易にするため、 本セクションは単純で人間が読める診断表記を定義する。 実際の交換は常にバイナリ形式で行われる。

これは本当に診断形式であり、解析されることを意図していない点に 注意する。したがって、本書では(ABNF のような)形式的定義は与えない。 (設定ファイル内で CBOR データ項目を表現するためのテキストベース形式を探している 実装者は、YAML [YAML] も 検討したい場合がある。)

診断表記は、RFC 8259 で定義される JSON に大まかに基づき、 必要に応じてそれを拡張している。

この表記は、数値(整数および浮動小数点)、True(>true<)、 False(>false<)、Null(>null<)、UTF-8 文字列、配列、 およびマップについて JSON 構文を借用する (マップは JSON ではオブジェクトと呼ばれる。診断表記はここで、 キー位置に任意のデータ項目を許可することにより JSON を拡張する)。 Undefined は JavaScript と同様に >undefined< と書かれる。 非有限浮動小数点数 Infinity、-Infinity、および NaN は、 この文中とまったく同じように書かれる(これは JavaScript で書くことができる方法でもあるが、 JSON はそれらを許可しない)。タグは、タグ番号の整数値として書かれ、 その後に括弧内のタグ内容が続く。たとえば、RFC 3339(ISO 8601)で指定される形式の日付は、 次のように表記できる。

0("2013-03-21T20:04:00Z")

または、等価な相対時刻は次のようになる。

1(1363896240)

バイト文字列は、いずれかの base 符号化で、パディングなしで、 単一引用符で囲まれ、base16 には >h<、base32 には >b32<、 base32hex には >h32<、base64 または base64url には >b64< を 接頭する形で表記される(実際の符号化は重ならないため、 文字列は曖昧でないままである)。たとえば、バイト文字列 0x12345678 は、 h'12345678'、b32'CI2FM6A'、または b64'EjRWeA' と書くことができる。

未割り当ての単純値は、括弧内に適切な整数を入れた "simple()" として与えられる。たとえば、"simple(42)" は メジャー型 7、値 42 を示す。

ここで定義された診断表記への有用な拡張の多くは、 [RFC8610] の付録 G「Extended Diagnostic Notation」 (EDN)で提供されている。 同様に、本書で扱われていない NaN ペイロードに関する文書化を提供するために、 この表記は別文書で拡張され得る。

8.1. 符号化インジケータ

複数の代替表現のうちどれが実際に使用されたかを 診断表記で示すことが有用な場合がある。たとえば、 診断デコーダによって >1.5< と書かれたデータ項目は、 半精度、単精度、または倍精度浮動小数点数として符号化されていた可能性がある。

符号化インジケータの規約は、アンダースコアで始まり、 それに続く英数字またはアンダースコアであるすべての文字からなるものは 符号化インジケータであり、この情報に関心のない者は無視できる、というものである。 たとえば、_ または _3 である。 符号化インジケータは常に任意である。

マップの開始中括弧または配列の開始角括弧の後に単一の アンダースコアを書くことで、そのデータ項目が不定長形式で 表現されたことを示せる。たとえば、[_ 1, 2] は、 データ項目 [1, 2] を表現するために不定長表現が使用されたことを示す インジケータを含む。

アンダースコアに十進数字 n が続くものは、 先行する項目(または配列およびマップの場合は、先行する角括弧または 中括弧で始まる項目)が追加情報値 24+n で符号化されたことを示す。 たとえば、1.5_1 は半精度浮動小数点数であり、 1.5_3 は倍精度として符号化されている。この符号化インジケータは 付録 A には示されていない。 (符号化インジケータ "_" は、したがって使用されない完全形 "_7" の 省略形であることに注意する。)

不定長のバイト文字列およびテキスト文字列の詳細なチャンク構造は、 (_ h'0123', h'4567') および (_ "foo", "bar") の形で 表記できる。しかし、内部にチャンクを持たない不定長文字列については、 (_ ) はバイト文字列(0x5fff)を意味するのか、テキスト文字列 (0x7fff)を意味するのかが曖昧であるため、使用されない。 代わりに基本形 ''_ および ""_ を使用でき、これらはチャンクがない場合だけのために 予約されている。これは、空チャンクだけを持つ(許可されているが 実際には有用ではない)符号化の短縮形ではない。そのようなものは、 チャンク構造を保持するために (_ '')、(_ "") などとして 表記する必要がある。

9. IANA に関する考慮事項

IANA は新しい CBOR 値のために 2 つのレジストリを作成した。 これらのレジストリは別個であり、すなわち包括的なレジストリの下にはなく、 [RFC8126] の規則に従う。 IANA はまた、新しいメディア型、関連する CoAP Content-Format エントリ、 および構造化構文接尾辞を割り当てた。

9.1. CBOR Simple Values Registry

IANA は [IANA.cbor-simple-values] に "Concise Binary Object Representation (CBOR) Simple Values" レジストリを 作成した。初期値は 表 4 に示されている。

範囲 0 から 19 の新しいエントリは Standards Action によって 割り当てられる。 [RFC8126]。 連続したブロック(もしあれば)のために下位番号を予約するため、 IANA が番号 16 から始めて値を割り当てることが提案される。

範囲 32 から 255 の新しいエントリは Specification Required によって割り当てられる。

9.2. CBOR Tags Registry

IANA は [IANA.cbor-tags] に "Concise Binary Object Representation (CBOR) Tags" レジストリを作成した。 [RFC7049] で定義されたタグは セクション 3.4 で詳細に説明されており、 それ以降にも他のタグがすでに定義されている。

範囲 0 から 23(「1+0」)の新しいエントリは Standards Action によって 割り当てられる。範囲 24 から 255(「1+1」)および 256 から 32767 (「1+2」の下位半分)の新しいエントリは Specification Required によって割り当てられる。範囲 32768 から 18446744073709551615 (「1+2」の上位半分、「1+4」、および「1+8」)の新しいエントリは First Come First Served によって割り当てられる。登録要求のテンプレートは 次のとおりである。

  • データ項目
  • セマンティクス(短い形式)

さらに、First Come First Served 要求には次を含めるべきである。

  • 連絡先
  • セマンティクスの説明(URL) -- この説明は 任意である。URL は Internet-Draft や Web ページのようなものを指すことができる。

First Come First Served 範囲を使用し、 32 ビットで表現できないタグ番号(すなわち 4294967295 より大きいもの)を 提案する申請者は、これが 64 ビット数値をサポートしない実装との 相互運用性を低下させ得ることを認識すべきである。

9.3. Media Types Registry

単一の符号化 CBOR データ項目に対するインターネットメディア型 [RFC6838](「MIME 型」)は、 "Media Types" レジストリ [IANA.media-types] で 定義される "application/cbor" である。

型名:
application
サブタイプ名:
cbor
必須パラメータ:
n/a
任意パラメータ:
n/a
符号化に関する考慮事項:
バイナリ
セキュリティに関する考慮事項:
RFC 8949 の セクション 10 を参照。
相互運用性に関する考慮事項:
n/a
公開仕様:
RFC 8949
このメディア型を使用するアプリケーション:
多数
追加情報:


マジックナンバー:
n/a
ファイル拡張子:
.cbor
Macintosh ファイルタイプコード:
n/a
さらなる情報のための連絡先となる人物およびメールアドレス:
IETF CBOR Working Group (cbor@ietf.org) または IETF Applications and Real-Time Area (art@ietf.org)
意図される用途:
COMMON
使用上の制限:
なし
著者:
IETF CBOR Working Group (cbor@ietf.org)
変更管理者:
The IESG (iesg@ietf.org)

9.4. CoAP Content-Format Registry

CBOR 用の CoAP Content-Format は、 "Constrained RESTful Environments (CoRE) Parameters" レジストリ [IANA.core-parameters] 内の "CoAP Content-Formats" サブレジストリに登録されている。

メディア型:
application/cbor
符号化:
-
ID:
60
参照:
RFC 8949

9.5. Structured Syntax Suffix Registry

単一の符号化 CBOR データ項目に基づくメディア型のための 構造化構文接尾辞 [RFC6838] は +cbor であり、IANA はこれを "Structured Syntax Suffixes" レジストリ [IANA.structured-suffix] に登録している。

名称:
簡潔なバイナリオブジェクト表現 (CBOR)
+suffix:
+cbor
参照:
RFC 8949
符号化に関する考慮事項:
CBOR はバイナリ形式である。
相互運用性に関する考慮事項:
n/a
フラグメント識別子に関する考慮事項:

+cbor に対して指定されるフラグメント識別子の構文およびセマンティクスは、 "application/cbor" に対して指定されるものと同じであるべきである (SHOULD)。(RFC 8949 の公開時点で、 "application/cbor" に対して定義されたフラグメント識別構文は存在しない。)

特定の "xxx/yyy+cbor" に対するフラグメント識別子の 構文およびセマンティクスは、次のように処理されるべきである (SHOULD)。

  • +cbor で定義されるケースで、 フラグメント識別子が +cbor の規則に従って解決される場合は、 +cbor で指定されるとおりに処理する。
  • +cbor で定義されるケースで、 フラグメント識別子が +cbor の規則に従って解決されない場合は、 "xxx/yyy+cbor" で指定されるとおりに処理する。
  • +cbor で定義されていないケースでは、 "xxx/yyy+cbor" で指定されるとおりに処理する。
セキュリティに関する考慮事項:
RFC 8949 の セクション 10 を参照。
連絡先:
IETF CBOR Working Group (cbor@ietf.org) または IETF Applications and Real-Time Area (art@ietf.org)
著者/変更管理者:
IETF

10. セキュリティに関する考慮事項

ネットワークに面したアプリケーションは、受信データに対する 処理ロジックに脆弱性を示す可能性がある。複雑なパーサは、 ノードをリモートからクラッシュさせる能力、さらにはその上で任意のコードを リモートから実行する能力など、そのような脆弱性の発生源となりやすいことが よく知られている。CBOR は、パーサの複雑さを低減し、可能な場合には 符号化可能な値の全範囲に意味を与えることで、そのような脆弱性を 導入する機会を狭めようとする。

CBOR デコーダは、検証されていない入力を処理する最初の段階として 使用されることが多いため、CBOR データ項目を復号するシステムを破損させたり、 オーバーランさせたり、制御を奪取したりするように設計され得る、あらゆる種類の 敵対的入力に対して十分に備えておく必要がある。CBOR デコーダは、 入力がファイアウォールによって検査されている場合、TLS などの安全なチャネルを通ってきた場合、 暗号化または署名されている場合、 または信頼されると推定される他の情報源から来た場合であっても、 すべての入力が敵対的であり得ると仮定する必要がある。

セクション 4.1 は、 非優先シリアライゼーションを使用する CBOR エンコーダからの入力を、 制約された CBOR デコーダで使用する場合の相互運用性の制限例を示す。 単一のデータ項目が、そのような制約されたデコーダと完全なデコーダの両方によって 消費される場合、コンテンツを注入または操作できる攻撃者に悪用され得る セキュリティ問題につながる可能性がある。

本文書全体で論じているように、ある状況では「等価」とみなされ、 別の状況では「等価でない」とみなされ得る値が多数存在する。 一例を挙げるだけでも、数値「one」の数値は整数または bignum として 表現される可能性がある。CBOR 入力を解釈するシステムは、数値「one」について どちらの形式も受け入れるか、一方(または両方)の形式を拒否するかもしれない。 そのような受け入れまたは拒否は、解釈された入力を使用するプログラムに セキュリティ上の影響を及ぼす可能性がある。

敵対的入力は、バッファをオーバーランさせたり、 整数演算をオーバーフローまたはアンダーフローさせたり、その他の復号の妨害を 引き起こしたりするように構築される可能性がある。CBOR データ項目には、意図的に極端に大きい、または短すぎる長さやサイズが 含まれることがある。 リソース枯渇攻撃は、デコーダを誘導して非常に大きなデータ項目 (文字列、配列、マップ、さらには任意精度数)を割り当てさせたり、 深く入れ子になった項目を設定してスタック深度を使い果たさせたりしようとする可能性がある。 デコーダは、これらの攻撃を緩和するための適切なリソース管理を持つ必要がある。 (非常に大きなサイズが与えられた項目は、整数オーバーフロー脆弱性を 悪用しようとすることもある。)

CBOR デコーダは、定義上、整形式の CBOR だけを受け入れる。 これは堅牢性への第一歩である。整形式の CBOR でない入力は、 整形式性の欠如が検出された時点以降、さらなる処理を引き起こさない。 可能であれば、この時点までに復号されたデータは、CBOR デコーダを使用する アプリケーションに影響を与えるべきではない。

整形式性を確認することに加えて、CBOR デコーダは CBOR データに対して 妥当性検査を実行することもある。あるいは、それらの検査を デコーダを使用するアプリケーションに委ねることもできる。この選択は デコーダで明確に文書化される必要がある。CBOR レベルでの妥当性を超えて、 アプリケーションは、入力が CBOR でシリアライズされたアプリケーションプロトコルと 整合していることも確認する必要がある。

入力検査自体がリソースを消費する場合がある。これは通常、入力のサイズに 対して線形であり、攻撃者は入力検証で防御側が費やすリソースに見合うリソースを 費やさなければならないことを意味する。 しかし、攻撃者は、標的のデコーダが処理するのに、攻撃者が生成するよりも 長い時間がかかる入力を作成できる可能性がある。 任意精度数の処理は線形の労力を超えることがある。また、デコーダがマップの メモリ内表現を構築するために使用する一部のハッシュテーブル実装は、 秘密鍵([SIPHASH_LNCS] のセクション 7、 および [SIPHASH_OPEN] を参照)または 何らかの他の緩和策が用いられない限り、二次的な労力を費やすよう攻撃され得る。 このような超線形の労力は、攻撃者によって入力検証器の時点またはそれ以前で リソースを枯渇させるために悪用され得る。したがって、CBOR デコーダ実装では これらを避ける必要がある。タグ番号の定義とその実装は、この種の セキュリティに関する考慮事項を追加し得ることに注意する。この場合、それは タグ番号定義のセキュリティに関する考慮事項で論じられるべきである。

CBOR エンコーダはネットワークから直接入力を受け取らないため、 CBOR デコーダと同じ方法で直接攻撃されるわけではない。 しかし、CBOR エンコーダは、実装内の別のレベルから入力を受け取る API を 持つことが多く、その API を通じて攻撃され得る。その API の設計および実装は、 その呼び出し元の挙動が敵対的入力またはコーディングミスに基づく可能性があると 仮定すべきである。バッファオーバーラン、整数演算のオーバーフローおよび アンダーフロー、ならびにエンコーダを妨害することを狙ったその他のそのような エラーについて、入力を検査すべきである。

プロトコルは、潜在的な複数の解釈が信頼できる形で 単一の解釈へ減らされるように定義されるべきである。たとえば、攻撃者は マップ内の重複キーなどの無効な入力を利用したり、数値処理における 精度の違いを悪用したりして、あるアプリケーションが、2 番目のアプリケーションで 使用される解釈とは異なる解釈に基づいて判断するようにできる可能性がある。 一貫した解釈を容易にするために、エンコーダおよびデコーダ実装は 妥当性検査モードの動作を提供すべきである (セクション 5.4)。 ただし、汎用デコーダは、アプリケーションが入力データに課すすべての要件を 知ることはできないことに注意する。したがって、アプリケーションが独自の 入力検査を実行する責任を免除するものではない。また、定義済みタグ番号の集合は 発展するため、アプリケーションは、使用している汎用デコーダがまだ妥当性検査を サポートしていないタグ番号を用いる場合がある。したがって、汎用デコーダは、 どのタグ番号をサポートし、それらのタグ番号および基本 CBOR (UTF-8 検査、重複マップキー検査)に対してどの妥当性検査を提供するかを 文書化する必要がある。

セクション 3.4.3 は、 数値を符号化するために基本整数ではなく bignum 表現という非優先の選択を用いることは、 アプリケーションセマンティクスを持つことを意図していないと述べている。 しかし、CBOR データを受け取るアプリケーションが基本汎用データモデルのデコーダを 使用している場合、それはそのようなセマンティクスを持つことがある。この不一致は、 2 つのセマンティクス集合が異なる場合にセキュリティ問題を引き起こす。 したがって、CBOR を使用するアプリケーションは、CBOR データの各使用に対して 使用するデータモデルを指定する必要がある。

CBOR データを他の形式に変換することは一般的である。多くの場合、 CBOR は他の形式よりも表現力のある型を持つ。これは JSON への一般的な変換で 特に当てはまる。型情報の喪失は、表現力の低いデータを処理するシステムに セキュリティ問題を引き起こす可能性がある。

セクション 6.2 は、 攻撃者がアプリケーションがその変換を実行していることを知っている場合に 攻撃を可能にし得る、CBOR と JSON の間で変換する一般的であり得る 使用シナリオを説明している。

[RFC4648] の base16 および base64 の使用、 ならびに [RFC3629] の UTF-8 の使用に関する セキュリティ上の考慮事項は、CBOR にも関連する。

11. 参考文献

11.1. 規範的参考文献

[C]
International Organization for Standardization, "Information technology - Programming languages - C", Fourth Edition, ISO/IEC 9899:2018, , <https://www.iso.org/standard/74528.html>.
[Cplusplus20]
International Organization for Standardization, "Programming languages - C++", Sixth Edition, ISO/IEC DIS 14882, ISO/IEC ISO/IEC JTC1 SC22 WG21 N 4860, , <https://isocpp.org/files/papers/N4860.pdf>.
[IEEE754]
IEEE, "IEEE Standard for Floating-Point Arithmetic", IEEE Std 754-2019, DOI 10.1109/IEEESTD.2019.8766229, <https://ieeexplore.ieee.org/document/8766229>.
[RFC2045]
Freed, N. and N. Borenstein, "Multipurpose Internet Mail Extensions (MIME) Part One: Format of Internet Message Bodies", RFC 2045, DOI 10.17487/RFC2045, , <https://www.rfc-editor.org/info/rfc2045>.
[RFC2119]
Bradner, S., "Key words for use in RFCs to Indicate Requirement Levels", BCP 14, RFC 2119, DOI 10.17487/RFC2119, , <https://www.rfc-editor.org/info/rfc2119>.
[RFC3339]
Klyne, G. and C. Newman, "Date and Time on the Internet: Timestamps", RFC 3339, DOI 10.17487/RFC3339, , <https://www.rfc-editor.org/info/rfc3339>.
[RFC3629]
Yergeau, F., "UTF-8, a transformation format of ISO 10646", STD 63, RFC 3629, DOI 10.17487/RFC3629, , <https://www.rfc-editor.org/info/rfc3629>.
[RFC3986]
Berners-Lee, T., Fielding, R., and L. Masinter, "Uniform Resource Identifier (URI): Generic Syntax", STD 66, RFC 3986, DOI 10.17487/RFC3986, , <https://www.rfc-editor.org/info/rfc3986>.
[RFC4287]
Nottingham, M., Ed. and R. Sayre, Ed., "The Atom Syndication Format", RFC 4287, DOI 10.17487/RFC4287, , <https://www.rfc-editor.org/info/rfc4287>.
[RFC4648]
Josefsson, S., "The Base16, Base32, and Base64 Data Encodings", RFC 4648, DOI 10.17487/RFC4648, , <https://www.rfc-editor.org/info/rfc4648>.
[RFC8126]
Cotton, M., Leiba, B., and T. Narten, "Guidelines for Writing an IANA Considerations Section in RFCs", BCP 26, RFC 8126, DOI 10.17487/RFC8126, , <https://www.rfc-editor.org/info/rfc8126>.
[RFC8174]
Leiba, B., "Ambiguity of Uppercase vs Lowercase in RFC 2119 Key Words", BCP 14, RFC 8174, DOI 10.17487/RFC8174, , <https://www.rfc-editor.org/info/rfc8174>.
[TIME_T]
The Open Group, "The Open Group Base Specifications", Section 4.16, 'Seconds Since the Epoch', Issue 7, 2018 Edition, IEEE Std 1003.1, , <https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap04.html#tag_04_16>.

11.2. 参考情報としての参考文献

[ASN.1]
International Telecommunication Union, "Information Technology - ASN.1 encoding rules: Specification of Basic Encoding Rules (BER), Canonical Encoding Rules (CER) and Distinguished Encoding Rules (DER)", ITU-T Recommendation X.690, , <https://www.itu.int/rec/T-REC-X.690-201508-I/en>.
[BSON]
Various, "BSON - Binary JSON", <http://bsonspec.org/>.
[CBOR-TAGS]
Bormann, C., "Notable CBOR Tags", Work in Progress, Internet-Draft, draft-bormann-cbor-notable-tags-02, , <https://tools.ietf.org/html/draft-bormann-cbor-notable-tags-02>.
[ECMA262]
Ecma International, "ECMAScript 2020 Language Specification", Standard ECMA-262, 11th Edition, , <https://www.ecma-international.org/publications/standards/Ecma-262.htm>.
[Err3764]
RFC Errata, Erratum ID 3764, RFC 7049, <https://www.rfc-editor.org/errata/eid3764>.
[Err3770]
RFC Errata, Erratum ID 3770, RFC 7049, <https://www.rfc-editor.org/errata/eid3770>.
[Err4294]
RFC Errata, Erratum ID 4294, RFC 7049, <https://www.rfc-editor.org/errata/eid4294>.
[Err4409]
RFC Errata, Erratum ID 4409, RFC 7049, <https://www.rfc-editor.org/errata/eid4409>.
[Err4963]
RFC Errata, Erratum ID 4963, RFC 7049, <https://www.rfc-editor.org/errata/eid4963>.
[Err4964]
RFC Errata, Erratum ID 4964, RFC 7049, <https://www.rfc-editor.org/errata/eid4964>.
[Err5434]
RFC Errata, Erratum ID 5434, RFC 7049, <https://www.rfc-editor.org/errata/eid5434>.
[Err5763]
RFC Errata, Erratum ID 5763, RFC 7049, <https://www.rfc-editor.org/errata/eid5763>.
[Err5917]
RFC Errata, Erratum ID 5917, RFC 7049, <https://www.rfc-editor.org/errata/eid5917>.
[IANA.cbor-simple-values]
IANA, "Concise Binary Object Representation (CBOR) Simple Values", <https://www.iana.org/assignments/cbor-simple-values>.
[IANA.cbor-tags]
IANA, "Concise Binary Object Representation (CBOR) Tags", <https://www.iana.org/assignments/cbor-tags>.
[IANA.core-parameters]
IANA, "Constrained RESTful Environments (CoRE) Parameters", <https://www.iana.org/assignments/core-parameters>.
[IANA.media-types]
IANA, "Media Types", <https://www.iana.org/assignments/media-types>.
[IANA.structured-suffix]
IANA, "Structured Syntax Suffixes", <https://www.iana.org/assignments/media-type-structured-suffix>.
[MessagePack]
Furuhashi, S., "MessagePack", <https://msgpack.org/>.
[PCRE]
Hazel, P., "PCRE - Perl Compatible Regular Expressions", <https://www.pcre.org/>.
[RFC0713]
Haverty, J., "MSDTP-Message Services Data Transmission Protocol", RFC 713, DOI 10.17487/RFC0713, , <https://www.rfc-editor.org/info/rfc713>.
[RFC6838]
Freed, N., Klensin, J., and T. Hansen, "Media Type Specifications and Registration Procedures", BCP 13, RFC 6838, DOI 10.17487/RFC6838, , <https://www.rfc-editor.org/info/rfc6838>.
[RFC7049]
Bormann, C. and P. Hoffman, "Concise Binary Object Representation (CBOR)", RFC 7049, DOI 10.17487/RFC7049, , <https://www.rfc-editor.org/info/rfc7049>.
[RFC7228]
Bormann, C., Ersue, M., and A. Keranen, "Terminology for Constrained-Node Networks", RFC 7228, DOI 10.17487/RFC7228, , <https://www.rfc-editor.org/info/rfc7228>.
[RFC7493]
Bray, T., Ed., "The I-JSON Message Format", RFC 7493, DOI 10.17487/RFC7493, , <https://www.rfc-editor.org/info/rfc7493>.
[RFC7991]
Hoffman, P., "The "xml2rfc" Version 3 Vocabulary", RFC 7991, DOI 10.17487/RFC7991, , <https://www.rfc-editor.org/info/rfc7991>.
[RFC8259]
Bray, T., Ed., "The JavaScript Object Notation (JSON) Data Interchange Format", STD 90, RFC 8259, DOI 10.17487/RFC8259, , <https://www.rfc-editor.org/info/rfc8259>.
[RFC8610]
Birkholz, H., Vigano, C., and C. Bormann, "Concise Data Definition Language (CDDL): A Notational Convention to Express Concise Binary Object Representation (CBOR) and JSON Data Structures", RFC 8610, DOI 10.17487/RFC8610, , <https://www.rfc-editor.org/info/rfc8610>.
[RFC8618]
Dickinson, J., Hague, J., Dickinson, S., Manderson, T., and J. Bond, "Compacted-DNS (C-DNS): A Format for DNS Packet Capture", RFC 8618, DOI 10.17487/RFC8618, , <https://www.rfc-editor.org/info/rfc8618>.
[RFC8742]
Bormann, C., "Concise Binary Object Representation (CBOR) Sequences", RFC 8742, DOI 10.17487/RFC8742, , <https://www.rfc-editor.org/info/rfc8742>.
[RFC8746]
Bormann, C., Ed., "Concise Binary Object Representation (CBOR) Tags for Typed Arrays", RFC 8746, DOI 10.17487/RFC8746, , <https://www.rfc-editor.org/info/rfc8746>.
[SIPHASH_LNCS]
Aumasson, J. and D. Bernstein, "SipHash: A Fast Short-Input PRF", Progress in Cryptology - INDOCRYPT 2012, pp. 489-508, DOI 10.1007/978-3-642-34931-7_28, , <https://doi.org/10.1007/978-3-642-34931-7_28>.
[SIPHASH_OPEN]
Aumasson, J. and D.J. Bernstein, "SipHash: a fast short-input PRF", <https://www.aumasson.jp/siphash/siphash.pdf>.
[YAML]
Ben-Kiki, O., Evans, C., and I.d. Net, "YAML Ain't Markup Language (YAML[TM]) Version 1.2", 3rd Edition, , <https://www.yaml.org/spec/1.2/spec.html>.

付録 A. 符号化された CBOR データ 項目の例

次の表は、これらの値に対する診断表記(左列)とともに、 16 進数での CBOR 符号化値(右列)をいくつか示す。 文字列 "\u00fc" は、単一の Unicode 文字 U+00FC(LATIN SMALL LETTER U WITH DIAERESIS, "ü") を含む UTF-8 文字列に対する診断表記の 一形式であることに注意する。同様に、"\u6c34" は、 単一の文字 U+6C34(CJK UNIFIED IDEOGRAPH-6C34, "水") を持つ診断表記における UTF-8 文字列であり、 しばしば「water」を表す。また、"\ud800\udd51" は、 単一の文字 U+10151(GREEK ACROPHONIC ATTIC FIFTY STATERS, "𐅑") を持つ診断表記における UTF-8 文字列である。 (これらすべての単一文字文字列は、ASCII のみの仕様が必要でないなら、 診断表記でネイティブ UTF-8 として表現することもできる点に注意する。) bignum に対して提供される診断表記では、それらの意図された数値が、 タグ付きバイト文字列(2(h'010000000000000000') など)ではなく、 10 進数(18446744073709551616 など)として示される。

表 6: 符号化された CBOR データ 項目の例
診断表記 符号化
0 0x00
1 0x01
10 0x0a
23 0x17
24 0x1818
25 0x1819
100 0x1864
1000 0x1903e8
1000000 0x1a000f4240
1000000000000 0x1b000000e8d4a51000
18446744073709551615 0x1bffffffffffffffff
18446744073709551616 0xc249010000000000000000
-18446744073709551616 0x3bffffffffffffffff
-18446744073709551617 0xc349010000000000000000
-1 0x20
-10 0x29
-100 0x3863
-1000 0x3903e7
0.0 0xf90000
-0.0 0xf98000
1.0 0xf93c00
1.1 0xfb3ff199999999999a
1.5 0xf93e00
65504.0 0xf97bff
100000.0 0xfa47c35000
3.4028234663852886e+38 0xfa7f7fffff
1.0e+300 0xfb7e37e43c8800759c
5.960464477539063e-8 0xf90001
0.00006103515625 0xf90400
-4.0 0xf9c400
-4.1 0xfbc010666666666666
Infinity 0xf97c00
NaN 0xf97e00
-Infinity 0xf9fc00
Infinity 0xfa7f800000
NaN 0xfa7fc00000
-Infinity 0xfaff800000
Infinity 0xfb7ff0000000000000
NaN 0xfb7ff8000000000000
-Infinity 0xfbfff0000000000000
false 0xf4
true 0xf5
null 0xf6
undefined 0xf7
simple(16) 0xf0
simple(255) 0xf8ff
0("2013-03-21T20:04:00Z") 0xc074323031332d30332d32315432303a 30343a30305a
1(1363896240) 0xc11a514b67b0
1(1363896240.5) 0xc1fb41d452d9ec200000
23(h'01020304') 0xd74401020304
24(h'6449455446') 0xd818456449455446
32("http://www.example.com") 0xd82076687474703a2f2f7777772e6578 616d706c652e636f6d
h'' 0x40
h'01020304' 0x4401020304
"" 0x60
"a" 0x6161
"IETF" 0x6449455446
"\"\\" 0x62225c
"\u00fc" 0x62c3bc
"\u6c34" 0x63e6b0b4
"\ud800\udd51" 0x64f0908591
[] 0x80
[1, 2, 3] 0x83010203
[1, [2, 3], [4, 5]] 0x8301820203820405
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25] 0x98190102030405060708090a0b0c0d0e 0f101112131415161718181819
{} 0xa0
{1: 2, 3: 4} 0xa201020304
{"a": 1, "b": [2, 3]} 0xa26161016162820203
["a", {"b": "c"}] 0x826161a161626163
{"a": "A", "b": "B", "c": "C", "d": "D", "e": "E"} 0xa5616161416162614261636143616461 4461656145
(_ h'0102', h'030405') 0x5f42010243030405ff
(_ "strea", "ming") 0x7f657374726561646d696e67ff
[_ ] 0x9fff
[_ 1, [2, 3], [_ 4, 5]] 0x9f018202039f0405ffff
[_ 1, [2, 3], [4, 5]] 0x9f01820203820405ff
[1, [2, 3], [_ 4, 5]] 0x83018202039f0405ff
[1, [_ 2, 3], [4, 5]] 0x83019f0203ff820405
[_ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25] 0x9f0102030405060708090a0b0c0d0e0f 101112131415161718181819ff
{_ "a": 1, "b": [_ 2, 3]} 0xbf61610161629f0203ffff
["a", {_ "b": "c"}] 0x826161bf61626163ff
{_ "Fun": true, "Amt": -2} 0xbf6346756ef563416d7421ff

付録 B. 初期バイト用ジャンプ表

簡潔にするため、このジャンプ表は、将来の拡張のために 予約されている初期バイトを示していない。また、任意機能に使用できる 初期バイトについても一部のみを示している。(すべての 符号なし整数はネットワークバイト順である。)

表 7: 初期バイト用ジャンプ表
バイト 構造/セマンティクス
0x00..0x17 符号なし整数 0x00..0x17 (0..23)
0x18 符号なし整数(1 バイト uint8_t が続く)
0x19 符号なし整数(2 バイト uint16_t が続く)
0x1a 符号なし整数(4 バイト uint32_t が続く)
0x1b 符号なし整数(8 バイト uint64_t が続く)
0x20..0x37 負の整数 -1-0x00..-1-0x17 (-1..-24)
0x38 負の整数 -1-n(n 用の 1 バイト uint8_t が続く)
0x39 負の整数 -1-n(n 用の 2 バイト uint16_t が続く)
0x3a 負の整数 -1-n(n 用の 4 バイト uint32_t が続く)
0x3b 負の整数 -1-n(n 用の 8 バイト uint64_t が続く)
0x40..0x57 バイト文字列(0x00..0x17 バイトが続く)
0x58 バイト文字列(n 用の 1 バイト uint8_t、 その後に n バイトが続く)
0x59 バイト文字列(n 用の 2 バイト uint16_t、 その後に n バイトが続く)
0x5a バイト文字列(n 用の 4 バイト uint32_t、 その後に n バイトが続く)
0x5b バイト文字列(n 用の 8 バイト uint64_t、 その後に n バイトが続く)
0x5f バイト文字列、バイト文字列が続き、 "break" で終了する
0x60..0x77 UTF-8 文字列(0x00..0x17 バイトが続く)
0x78 UTF-8 文字列(n 用の 1 バイト uint8_t、 その後に n バイトが続く)
0x79 UTF-8 文字列(n 用の 2 バイト uint16_t、 その後に n バイトが続く)
0x7a UTF-8 文字列(n 用の 4 バイト uint32_t、 その後に n バイトが続く)
0x7b UTF-8 文字列(n 用の 8 バイト uint64_t、 その後に n バイトが続く)
0x7f UTF-8 文字列、UTF-8 文字列が続き、 "break" で終了する
0x80..0x97 配列(0x00..0x17 個のデータ項目が続く)
0x98 配列(n 用の 1 バイト uint8_t、その後に n 個のデータ項目が続く)
0x99 配列(n 用の 2 バイト uint16_t、その後に n 個のデータ項目が続く)
0x9a 配列(n 用の 4 バイト uint32_t、その後に n 個のデータ項目が続く)
0x9b 配列(n 用の 8 バイト uint64_t、その後に n 個のデータ項目が続く)
0x9f 配列、データ項目が続き、"break" で 終了する
0xa0..0xb7 マップ(0x00..0x17 対のデータ項目が続く)
0xb8 マップ(n 用の 1 バイト uint8_t、その後に n 対のデータ項目が続く)
0xb9 マップ(n 用の 2 バイト uint16_t、その後に n 対のデータ項目が続く)
0xba マップ(n 用の 4 バイト uint32_t、その後に n 対のデータ項目が続く)
0xbb マップ(n 用の 8 バイト uint64_t、その後に n 対のデータ項目が続く)
0xbf マップ、データ項目のペアが続き、 "break" で終了する
0xc0 テキストベースの日時(データ項目が続く。 セクション 3.4.1 を参照)
0xc1 エポックベースの日時(データ項目が続く。 セクション 3.4.2 を参照)
0xc2 符号なし bignum(データ項目 "byte string" が続く)
0xc3 負の bignum(データ項目 "byte string" が続く)
0xc4 十進小数(データ項目 "array" が続く。 セクション 3.4.4 を参照)
0xc5 bigfloat(データ項目 "array" が続く。セクション 3.4.4 を参照)
0xc6..0xd4 (タグ)
0xd5..0xd7 想定変換(データ項目が続く。セクション 3.4.5.2 を参照)
0xd8..0xdb (追加のタグ。タグ番号の 1/2/4/8 バイトと その後にデータ項目が続く)
0xe0..0xf3 (単純値)
0xf4 false
0xf5 true
0xf6 null
0xf7 undefined
0xf8 (単純値、1 バイトが続く)
0xf9 半精度浮動小数点数(2 バイト IEEE 754)
0xfa 単精度浮動小数点数(4 バイト IEEE 754)
0xfb 倍精度浮動小数点数(8 バイト IEEE 754)
0xff "break" 停止コード

付録 C. 擬似コード

CBOR 項目の整形式性は、 図 1 の擬似コードで検査できる。データが整形式であるための 必要十分条件は次のとおりである。

この擬似コードには次の前提条件がある。

well_formed は、整形式の定長項目については メジャー型を返すが、不定長項目については 99 を返す(または、 breakable が設定されている場合に限り、"break" 停止コードについて -1 を返す)ことに注意する。これは well_formed_indefinite で、 不定長文字列がチャンクとして定長文字列のみを含むことを確認するために使用される。

well_formed(breakable = false) {
  // 初期バイトを処理する
  ib = uint(take(1));
  mt = ib >> 5;
  val = ai = ib & 0x1f;
  switch (ai) {
    case 24: val = uint(take(1)); break;
    case 25: val = uint(take(2)); break;
    case 26: val = uint(take(4)); break;
    case 27: val = uint(take(8)); break;
    case 28: case 29: case 30: fail();
    case 31:
      return well_formed_indefinite(mt, breakable);
  }
  // 内容を処理する
  switch (mt) {
    // case 0, 1, 7 には内容がない。val だけを使用する
    case 2: case 3: take(val); break; // bytes/UTF-8
    case 4: for (i = 0; i < val; i++) well_formed(); break;
    case 5: for (i = 0; i < val*2; i++) well_formed(); break;
    case 6: well_formed(); break;     // 1 個の埋め込みデータ項目
    case 7: if (ai == 24 && val < 32) fail(); // 不正な simple
  }
  return mt;                    // 定長データ項目
}

well_formed_indefinite(mt, breakable) {
  switch (mt) {
    case 2: case 3:
      while ((it = well_formed(true)) != -1)
        if (it != mt)           // 定長チャンクが必要
          fail();               //    同じ型のもの
      break;
    case 4: while (well_formed(true) != -1); break;
    case 5: while (well_formed(true) != -1) well_formed(); break;
    case 7:
      if (breakable)
        return -1;              // break out を通知する
      else fail();              // 囲む不定長項目がない
    default: fail();            // 誤った mt
  }
  return 99;                    // 不定長データ項目
}
図 1: 整形式性検査のための 擬似コード

完全な CBOR デコーダの残りの複雑さは、 復号されたデータを適切な形式でアプリケーションに提示することに関するものである点に 注意する。

メジャー型 0 および 1 は、正/負に対して実際に if-then-else を行わなくても、符号付き整数から C で符号化できるように 設計されている(図 2)。これは、 メジャー型 1 の変換である (-1-n) が、C の符号なし算術における ~n(ビット単位の補数)と同じであるという事実を用いる。すると ~n は、 負の場合には (-1)^n として表現でき、非負の場合には 0^n が n を 変更しないままにする。数値の符号は、その数値のビット長より 1 ビット少ない数だけ 算術シフトすることにより、負の場合は -1、非負(0 または正)の場合は 0 に変換できる(たとえば、64 ビット数の場合は 63 だけシフトする)。

void encode_sint(int64_t n) {
  uint64t ui = n >> 63;    // 符号を全長に拡張する
  unsigned mt = ui & 0x20; // (シフト済みの)メジャー型を取り出す
  ui ^= n;                 // 負数を補数にする
  if (ui < 24)
    *p++ = mt + ui;
  else if (ui < 256) {
    *p++ = mt + 24;
    *p++ = ui;
  } else
       ...
図 2: 符号付き整数を符号化するための 擬似コード

これらのコード片で使用される C 言語のプロファイルに関する いくつかの具体的な仮定については、セクション 1.2 を参照。

付録 D. 半精度

半精度浮動小数点数は 2008 年に IEEE 754 に追加されたばかりであるため [IEEE754]、今日のプログラミングプラットフォームでは それらのサポートがまだ限定的であることが多い。 そのようなサポートがなくても、少なくとも復号サポートを含めることは非常に容易である。 C 言語による半精度浮動小数点数の小さなデコーダの例を 図 3 に示す。Python 用の同様のプログラムは 図 4 にあり、このコードは、その 2 バイト値が すでにネットワークバイト順の(符号なし short)整数として復号されていることを仮定する (付録 C の擬似コードによって行われるのと同様である)。

#include <math.h>

double decode_half(unsigned char *halfp) {
  unsigned half = (halfp[0] << 8) + halfp[1];
  unsigned exp = (half >> 10) & 0x1f;
  unsigned mant = half & 0x3ff;
  double val;
  if (exp == 0) val = ldexp(mant, -24);
  else if (exp != 31) val = ldexp(mant + 1024, exp - 25);
  else val = mant == 0 ? INFINITY : NAN;
  return half & 0x8000 ? -val : val;
}
図 3: 半精度デコーダのための C コード
import struct
from math import ldexp

def decode_single(single):
    return struct.unpack("!f", struct.pack("!I", single))[0]

def decode_half(half):
    valu = (half & 0x7fff) << 13 | (half & 0x8000) << 16
    if ((half & 0x7c00) != 0x7c00):
        return ldexp(decode_single(valu), 112)
    return decode_single(valu | 0x7f800000)
図 4: 半精度デコーダのための Python コード

付録 E. 他のバイナリ形式と CBOR の設計目的との比較

CBOR の提案は、コンピュータそのものの歴史と同じくらい 長いバイナリ形式の歴史に沿うものである。異なる形式には 異なる目的があった。ほとんどの場合、その形式の目的は 明示されていなかったが、形式が最初に使用された文脈から推測できることもある。 一部の形式は汎用的に使用できることを意図していたが、歴史が示すように、 すべてのプロトコルおよびアプリケーションの需要を満たすバイナリ形式は存在しない。

CBOR は、一連の目的から出発し、それらだけを満たそうとする点で、 これらの形式の多くとは異なる。本セクションは、読者が特定のプロトコルまたは アプリケーションに CBOR を使用するか、それとも別の形式を使用するかを判断しやすくするため、 数十ある形式のうちいくつかを CBOR の目的と比較する。

ここでの議論は、どの形式に対する批判を意図したものでもない点に注意する。 我々の知る限り、CBOR 以前には、我々が割り当てた優先順位で CBOR の目的を カバーすることを意図した形式はなかった。セクション 1.1 の 目的を簡潔にまとめると次のとおりである。

  1. インターネット標準の最も一般的なデータ形式を曖昧さなく符号化すること
  2. エンコーダまたはデコーダのコードのコンパクトさ
  3. スキーマ記述が不要であること
  4. 十分にコンパクトなシリアライゼーション
  5. 制約されたアプリケーションおよび制約されていないアプリケーションへの適用可能性
  6. 良好な JSON 変換
  7. 拡張性

異なる設計目的の集合に関して CBOR と他の形式を論じたものは、 [RFC8618] のセクション 5 および付録 C で提供されている。

E.1. ASN.1 DER、BER、および PER

[ASN.1] には多くの シリアライゼーションがある。IETF では、DER と BER が 最も一般的である。シリアライズされた出力は、多くの項目について 特にコンパクトではなく、数値項目を復号するために必要なコードは、 制約デバイス上では複雑になる場合がある。

Packed Encoding Rules(PER)のいくつかの変種のうち一つを 採用した IETF プロトコルは、ほとんど(あるとしても)存在しない。 これには多くの理由があり得るが、よく述べられる理由の一つは、 PER がデータ項目の表面構造の解析にさえスキーマを利用するため、 重要なツールサポートを必要とすることである。使用されている ASN.1 スキーマ言語には異なるバージョンがあり、それも採用を妨げてきた。

E.2. MessagePack

[MessagePack] は、 簡潔で、広く実装されているカウント付きバイナリ シリアライゼーション形式であり、多くの性質で CBOR に似ているが、 やや規則性が低い。データモデルは JSON データを表現するために使用できる一方で、 MessagePack は多くのリモートプロシージャコール(RPC)アプリケーションや データの長期保存にも使用されてきた。

MessagePack は 2011 年ごろに最初に公開されて以来、 本質的に安定している。まだ移行は行われていない。MessagePack の発展は、 既存の保存データとの完全な後方互換性を維持しなければならないという命令と、 拡張に利用できるバイトコードがわずかしか残っていないことによって妨げられている。 MessagePack ユーザーコミュニティから長年にわたり、符号化において バイナリ文字列とテキスト文字列を分離するよう繰り返し要求された結果、 最近では、MessagePack の "raw" データをバイナリデータとテキストデータの 用途の間で曖昧なままにする拡張提案につながった。MessagePack の拡張機構は 依然として不明確である。

E.3. BSON

[BSON] は、 MongoDB データベースにおける JSON 風のマップ(JSON オブジェクト)の 保存のために開発されたデータ形式である。その主な特徴は、 インプレース更新の能力であり、これはコンパクトな表現を妨げる。 BSON はマップキーを除いてカウント付き表現を使用し、マップキーは null バイトで終端される。BSON は JSON 風のオブジェクトをワイヤ上で 表現するために使用できるが、その仕様はデータベースアプリケーションの 要件に支配されており、ややバロック的になっている。BSON 拡張がどのように 実装されるかの状況は依然として不明確である。

E.4. MSDTP: RFC 713

Message Services Data Transmission(MSDTP)は、 コンパクトなメッセージ形式の非常に初期の例である。これは 1976 年に 書かれた [RFC0713] で説明されている。これは 歴史的価値のためにここに含めているのであり、広く使用されたからではない。

E.5. ワイヤ上での 簡潔さ

CBOR のエンコーダおよびデコーダのコードコンパクト性という 設計目的は、ワイヤ上での簡潔さという目的よりも優先順位が高いが、 多くの人はワイヤサイズに注目する。表 8 は、 単純な入れ子配列 [1, [2, 3]] の符号化例をいくつか示す。 不定長符号化の何らかの形式がその符号化でサポートされている場合は、 [_ 1, [2, 3]](外側の配列が不定長)も示されている。

表 8: 異なる簡潔さの水準の 例
形式 [1, [2, 3]] [_ 1, [2, 3]]
RFC 713 c2 05 81 c2 02 82 83
ASN.1 BER 30 0b 02 01 01 30 06 02 01 02 02 01 03 30 80 02 01 01 30 06 02 01 02 02 01 03 00 00
MessagePack 92 01 92 02 03
BSON 22 00 00 00 10 30 00 01 00 00 00 04 31 00 13 00 00 00 10 30 00 02 00 00 00 10 31 00 03 00 00 00 00 00
CBOR 82 01 82 02 03 9f 01 82 02 03 ff

付録 F. 整形式性エラーと 例

CBOR データ項目を復号する際に発生し得る整形式性エラーには、 基本的に 3 種類がある。

データが多すぎる:
消費されなかった入力バイトが残っている。 これは、入力バイトが正確に 1 つのデータ項目にまたがるとアプリケーションが 仮定した場合にのみエラーである。たとえば CBOR シーケンス [RFC8742] で行われるように、 アプリケーションが CBOR 符号化の自己区切り性を用いて データ項目の後に追加データを許可する場合、CBOR デコーダは、入力のどの部分が 消費されていないかを単に示すことができる。
データが少なすぎる:
利用可能な入力データは、 完全な CBOR データ項目のために、その末尾に追加のバイトを加える必要がある。 これは入力が切り詰められていることを示す場合がある。また、ランダムデータを CBOR として復号しようとするときにもよくあるエラーである。 ただし、一部のアプリケーションでは、これが実際にはエラーではない場合がある。 アプリケーションがまだすべてのデータを持っていると確信できず、追加の入力バイトを 取得するか待つことができるからである。そのようなアプリケーションの一部には、 出現し得る追加データ量に上限がある場合がある。この場合、デコーダは、 符号化された CBOR データ項目がこの上限内では完了できないことを示せる場合がある。
構文エラー:
入力データが CBOR 符号化の 要件と整合しておらず、末尾にデータを追加(または削除)しても 修復できない。

付録 C では、第 1 種のエラーは 最初の段落および箇条書き(「バイトが残っていない」ことを要求する)で扱われ、 第 2 種のエラーは第 2 の段落/箇条書き(「n バイトがもはや利用できない場合」に 失敗する)で扱われる。第 3 種のエラーは、擬似コードにおいて、次の順序で fail() を呼び出す具体的なインスタンスによって識別される。

F.1. 整形式ではない CBOR データ項目の例

このサブセクションは、整形式ではない CBOR データ項目の例を いくつか示す。各例はバイト列であり、それぞれ 16 進数で示される。 リスト内の複数の例はコンマで区切られる。

整形式性エラー第 1 種(データが多すぎる)の例は、 整形式の符号化済み CBOR データ項目にデータを追加することで容易に作成できる。

同様に、整形式性エラー第 2 種(データが少なすぎる)の例は、 整形式の符号化済み CBOR データ項目を切り詰めることで作成できる。 テストスイートでは、完了するために大量の追加を必要とする不完全なデータ項目 (たとえば、非常に大きなサイズの文字列の符号化を開始することによるもの)を 具体的にテストすると有益な場合がある。

入力の早すぎる終端は、ヘッド内、または囲まれたデータ内で 発生する可能性がある。囲まれたデータは、素の文字列である場合も、 カウント付きまたは "break" 停止コードで終了されるべきであった 囲まれたデータ項目である場合もある。

ヘッド内での入力の終端:
18, 19, 1a, 1b, 19 01, 1a 01 02, 1b 01 02 03 04 05 06 07, 38, 58, 78, 98, 9a 01 ff 00, b8, d8, f8, f9 00, fa 00 00, fb 00 00 00
データが短い定長文字列:
41, 61, 5a ff ff ff ff 00, 5b ff ff ff ff ff ff ff ff 01 02 03, 7a ff ff ff ff 00, 7b 7f ff ff ff ff ff ff ff 01 02 03
十分な項目で閉じられていない定長マップおよび配列:
81, 81 81 81 81 81 81 81 81 81, 82 00, a1, a2 01 02, a1 00, a2 00 00 00
タグ内容が続かないタグ番号:
c0
"break" 停止コードで閉じられていない不定長文字列:
5f 41 00, 7f 61 00
"break" 停止コードで閉じられていない不定長マップおよび配列:
9f, 9f 01 02, bf, bf 01 02 01 02, 81 9f, 9f 80 00, 9f 9f 9f 9f 9f ff ff ff ff, 9f 81 9f 81 9f 9f ff ff ff

整形式性エラー第 3 種(構文エラー)の 5 つの下位種別について、 いくつかの例を以下に示す。

下位種別 1:

予約済みの追加情報値:
1c, 1d, 1e, 3c, 3d, 3e, 5c, 5d, 5e, 7c, 7d, 7e, 9c, 9d, 9e, bc, bd, be, dc, dd, de, fc, fd, fe,
下位種別 2:

単純値の予約済み 2 バイト符号化:
f8 00, f8 01, f8 18, f8 1f
下位種別 3:

正しい型ではない不定長文字列チャンク:
5f 00 ff, 5f 21 ff, 5f 61 00 ff, 5f 80 ff, 5f a0 ff, 5f c0 00 ff, 5f e0 ff, 7f 41 00 ff
定長ではない不定長文字列チャンク:
5f 5f 41 00 ff ff, 7f 7f 61 00 ff ff
下位種別 4:

不定長項目の外側で単独で現れる break:
ff
定長配列、マップ、またはタグ内に現れる break:
81 ff, 82 00 ff, a1 ff, a1 ff 00, a1 00 ff, a2 00 00 ff, 9f 81 ff, 9f 82 9f 81 9f 9f ff ff ff ff
奇数個の項目につながる不定長マップ内の break (値位置の break):
bf 00 ff, bf 00 00 00 ff
下位種別 5:

追加情報 31 を持つメジャー型 0、1、6:
1f, 3f, df

付録 G. RFC 7049 からの変更

序論で論じたように、 本文書は RFC 7049 の交換形式との完全な互換性を維持しつつ、 RFC 7049 を正式に廃止する。本文書は、編集上の改善、詳細の追加、および 正誤表の修正を提供する。 本文書は、この形式の新しいバージョンを作成するものではない。

G.1. 正誤表の処理および 事務的変更

RFC 7049 に対する 2 つの検証済み正誤表、 [Err3764] および [Err3770] は、 本文中の 2 つの符号化例に関するものであり、修正された (セクション 3.4.3: "29" -> "49", セクション 5.5: "0b000_11101" -> "0b000_11001")。また、RFC 7049 には、単純値に数値 24 を使用する例 [Err5917] が 含まれていたが、これは整形式ではないため、この例は 削除された。正誤表報告 5763 [Err5763] は、 タグの定義の文言における誤りを指摘した。これは セクション 3.4 の書き換え中に解決された。 正誤表報告 5434 [Err5434] は、付録 E の Universal Binary JSON (UBJSON)の例が、正誤表報告提出時点で現行だった UBJSON のバージョンに もはや準拠していないことを指摘した。UBJSON 仕様は 2013 年以降完全に 変化していたことが判明したため、この例は削除された。その他の正誤表報告 [Err4409] [Err4963] [Err4964] は、標準的符号化のためのマップキーソート規則が 煩雑であると述べた。これにより、標準的符号化の提案が再考され、 (後述の)決定論的符号化の提案に置き換えられた。正誤表報告 4294 [Err4294] の編集上の提案も 実装された(セクション 3.2.2 の最後の例のコメントに "Second value" を追加して対称性を改善)。

その他の事務的変更には次が含まれる。

  • 新しい xml2rfc 機能 [RFC7991] の使用。
  • 使用される表記に関する説明の追加。
  • 参照の更新、たとえば RFC 4627 から [RFC8259] へ、 CNN-TERMS から [RFC7228] へ、 そして [ECMA262] の 5.1 版から 11 版へ。 [IEEE754] への参照の追加と 必要な定義の取り込み。 [C] および [Cplusplus20] への参照の追加。 さらに、付録 E の議論をさらに例示する [RFC8618] への参照の追加。
  • 診断表記の議論(セクション 8)において、 [RFC8610] で定義される "Extended Diagnostic Notation" (EDN)が現在言及されており、 NaN ペイロードを表現する際の空白が現在強調され、 チャンクを持たない不定長文字列の表現に関する説明が追加された (セクション 8.1)。
  • この付録の追加。

G.2. IANA に関する 考慮事項の変更

IANA に関する考慮事項は全般的に更新された(事務的変更、 たとえば現在は仕様の著者として CBOR Working Group を指している)。 それぞれの IANA レジストリへの参照が参考情報としての参考文献に 追加された。

"Concise Binary Object Representation (CBOR) Tags" レジストリ [IANA.cbor-tags] では、 256 から 32767("1+2" の下位半分)の空間にあるタグは、 もはや First Come First Served によって割り当てられない。この範囲は 現在 Specification Required である。

G.3. 提案およびその他の 情報的構成要素の変更

本文書の改訂中、正誤表報告への対処を超えて、 ワーキンググループは、多様なアプリケーションにおける CBOR の約 7 年間の経験を 活用した。これにより、説明のための表の追加を含む多くの編集上の変更だけでなく、 ある側面の強調と別の側面の弱調にもつながった。

重要な追加は セクション 2 であり、CBOR データモデルと、CBOR の処理に関わるその小さな変種を 論じている。これらの変種(基本汎用、拡張汎用、特定)に対する用語の導入は、 文書内の他の箇所でより簡潔な言語を可能にし、また実装および形式の拡張性機能に対する 期待を明確にする助けにもなる。

JSON エコシステムから派生した形式として、RFC 7049 は 当時 JavaScript から継承されていた JSON 数値システムの影響を受けていた。 JSON は、整数値と浮動小数点値を区別して提供しない (後者は形式上は十進である)。CBOR は数値のバイナリ表現を提供し、 それは整数値と浮動小数点値の間で異なる。実装および利用の経験から、 これら 2 つの数値領域の分離を本文書でより明確に描くべきであることが示唆された。 整数が浮動小数点値の代わりとしてシームレスに使用できることを示唆する文言は削除された。 また、JSON から CBOR へ変換する際のこれらの型の扱いについて、 (I-JSON [RFC7493] に基づく)提案が追加され、 特定の丸め機構の使用が推奨された。

データモデル内の単一の値について、CBOR はしばしば複数の 符号化オプションを提供する。新しいセクション(セクション 4)は、 「優先シリアライゼーション」(セクション 4.1)という用語を導入し、 さまざまな種類のデータ項目についてそれを定義する。この用語に基づいて、 同セクションは、CBOR ベースのプロトコルが "deterministic encoding"(セクション 4.2)をどのように 定義できるかを論じる。これは RFC 7049 の "canonical" および "canonicalization" という用語を避けるものである。 "Core Deterministic Encoding Requirements"(セクション 4.2.1) の提案は、そのようなプロトコル定義の符号化要件に対する汎用サポートを可能にする。 本文書はさらに、RFC 7049 で提案されたマップ順序付けを、符号化キーの単純な 辞書順序に簡素化することで、決定論的符号化の実装を容易にしている。 以前の提案の説明は代替として残され、現在は「長さ優先のマップキー順序付け」 (セクション 4.2.3)と呼ばれている。

整形式データおよび妥当なデータに関する用語は鋭くされ、 より厳密に使用されるようになった。例の外では、"syntax error"、 "decoding error"、"strict mode" など、より定義の曖昧な代替用語は避けられた。 また、アプリケーションが入力データに対して持つ、CBOR レベルの妥当性を超える 第 3 の要件レベルが明示的に示された。 整形式(そもそも処理可能)、妥当(妥当性検査を行う汎用デコーダで検査される)、 そして想定される入力(アプリケーションで検査される)は、 受け入れ可能性の階層として扱われる。

整形式ではない単純値の扱いは、本文と擬似コードで明確化された。 付録 F が追加され、整形式性エラーを論じ、 それらの例を提供している。擬似コードはより移植性の高いものに更新され、 いくつかの移植性に関する考慮事項が追加された。

妥当性の議論は 2 つの領域で鋭くされた。マップ妥当性 (重複キーの扱い)が明確化され、特定の実装選択の適用範囲が説明された。 また、タグ、タグ番号、およびタグ内容に関する用語を整理する中で、 タグ妥当性に関する議論が追加され、タグ内容に対する制限が、 一般的に、また特にタグ 1 について明確化された。

シリアライゼーション順序に依存するセマンティクスを持つタグを 定義することについて、実装上の注意(および将来のタグ定義のための注意)が セクション 3.4 に追加された。

タグ 35 は本文書によって定義されない。RFC 7049 の定義に基づく 登録はそのまま維持される。

セクション 3 では、 "argument" および "head" に関する用語が導入され、 その後の議論が簡素化された。

セキュリティに関する考慮事項(セクション 10)はほとんど書き換えられ、大幅に拡張された。その他の複数の箇所でも、 デコーダが整形式性エラーを単純に容認することはできないことが、本文書で より明示的に示されるようになった。

謝辞

CBOR は MessagePack に着想を得た。MessagePack は Sadayuki Furuhashi("frsyuki")によって開発され、 推進された。MessagePack へのこの参照は帰属表示のみを目的としている。CBOR は、 MessagePack のバージョンまたは置換を意図したものではなく、異なる設計目的と 要件を持つ。

元の MessagePack 仕様を超える機能の必要性は、 2012 年ごろのほぼ同時期に多くの人々に明らかになった。 BinaryPack は、binaryjs プロジェクトのために Eric Zhang によって 開発された MessagePack の小さな派生である。同様だが異なる拡張が、 Tim Caswell によって彼の msgpack-js および msgpack-js-browser プロジェクトのために作成された。多くの人々が、 テキスト文字列表現とバイト文字列表現を分離するための MessagePack 拡張に関する 議論に貢献してきた。

CBOR における追加情報の符号化は、 Klaus Hartke が CoAP のために設計した長さ情報の符号化に 着想を得た。

本文書はまた、多くの人々による提案を取り込んでいる。 特に Dan FrostJames MangerJeffrey YasskinJoe HildebrandKeith MooreLaurence LundbladeMatthew LepinskiMichael RichardsonNico WilliamsPeter OccilPhillip Hallam-BakerRay PolkStuart CheshireTim BrayTony FinchTony Hansen、および Yaron Sheffer である。Benjamin Kaduk は IESG 処理中に広範なレビューを提供した。 Éric VynckeErik KlineRobert Wilton、および Roman Danyliw は さらに IESG コメントを提供し、その中には Eve Schooler による IoT directorate レビューも含まれていた。

著者の連絡先

Carsten Bormann
Universität Bremen TZI
Postfach 330440
D-28359 Bremen
Germany
Paul Hoffman
ICANN