RFC 8949 CBOR 2020年12月
Bormann & Hoffman 標準化過程 [ページ]
ストリーム:
Internet Engineering Task Force (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 の交換形式との完全な互換性を維持します。この形式の新しいバージョンを 作成するものではありません。

このメモの位置付け

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

この文書は Internet Engineering Task Force (IETF) の成果物です。これは IETF コミュニティの合意を表しています。これは 公開レビューを受け、Internet Engineering Steering Group (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 の制約付きノード)。
    • この形式は、現代のマシンにおける データ表現を使用すべきです (たとえば、2進数から10進数への変換を必要としないこと)。
  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 個以上のデータ項目のシーケンスであり、さらに大きな 包含データ項目へ組み立てられていないもの(1 つの応用例については [RFC8742] を参照)。 データストリームを構成する 独立したデータ項目は、「トップレベルデータ 項目」と呼ばれることもあります。
整形式:
CBOR の構文構造に従うデータ項目。 整形式のデータ項目は、CBOR で定義されている値によって 暗示される初期バイト、バイト文字列 および/またはデータ項目を使用し、その後に余分なデータを含みません。CBOR デコーダーは、 定義上、整形式のデータ項目からのみ内容を返します。
妥当:
整形式であり、かつ CBOR データ項目に適用される セマンティック上の制約にも従うデータ項目(セクション 5.3)。
期待される:
通常の英語としての意味に加えて、「expected」という用語は、 アプリケーションが入力データに課す、CBOR の妥当性を超える 要件を記述するために使用されます。整形式(そもそも処理可能)、 妥当(妥当性を検査する汎用デコーダーによって確認済み)、 および期待される(アプリケーションによって確認済み)は、 受容可能性の階層を形成します。
ストリームデコーダー:
データストリームをデコードし、シーケンス内の各データ 項目を受信された時点で アプリケーションから利用可能にするプロセス。

Infinity、NaN (not a number)、負のゼロ、および非正規数などの浮動小数点値に関する用語と概念は、[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 と同様に数値として解釈され、次に、 表記内に明示された先行ゼロバイトを含め、ネットワークバイトオーダーの バイト文字列として解釈されます。

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

2. CBOR データモデル

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

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

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

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

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

2.1. 拡張された汎用データ モデル

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

  • false、true、null、および undefined (20..23 によって識別される単純値、セクション 3.3)
  • 上記よりも広い範囲 および高い精度を持つ整数値と浮動小数点値 (タグ番号 2 から 5、セクション 3.4)
  • 時点や RFC 3339 で定義される日付/時刻文字列などのアプリケーションデータ型(タグ番号 1 および 0、セクション 3.4)

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

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

汎用エンコーダーとデコーダーが false、true、および null (undefined は意図的に 除外されています)を、そのプログラミング環境に適した形式で表現できることが強く期待される一方で、 タグによって作成されるデータモデル拡張の実装は完全に 任意であり、実装品質の問題です。

2.2. 固有データモデル

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

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

3. CBOR エンコーディングの仕様

CBOR データ項目(セクション 2)は、 このセクションで説明する整形式のエンコード済みデータ項目を保持する バイト文字列へエンコードされ、またはそこからデコードされます。エンコーディングは、 初期バイトによって索引付けされた 付録 B の 表 7 にまとめられています。エンコーダーは 整形式の エンコードされたデータ項目だけを生成しなければなりません。 デコーダーは、整形式のエンコードされた CBOR データ項目ではない入力に 遭遇した場合、デコードされたデータ項目を返してはなりません(これは、 破損したエンコード済み 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)に続いて 2 バイトの 0x01f4 となります。これは10進数で 500 です。
メジャータイプ 1:
-264..-1 の範囲の負の整数(両端を含む)。項目の 値は -1 から引数を引いたものです。たとえば、整数 -500 は 0b001_11001(メジャータイプ 1、追加情報 25) に続いて 2 バイトの 0x01f3 となります。これは10進数で 499 です。
メジャータイプ 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 シーケンス」は少し異なるものです [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)を置いて表現します。 不定長文字列によって表されるデータ項目は、 各チャンクを連結したものです。チャンクが存在しない場合、データ項目は指定された型の空 文字列です。長さ 0 のチャンクは、特に 有用ではありませんが、許可されています。

不定長文字列標識 (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 は、 不定長エンコーディング(追加情報を 31 に設定)に使用される CBOR のメジャータイプを まとめたものです。

表 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 バイト列を 発行してはなりません。このようなシーケンスは 整形式ではありません。(これは、エンコーダーが false、true、 null、または undefined を 2 バイト列でエンコードできず、これらの 1 バイト バリアントだけが整形式であることを意味します。より一般的には、各 単純値には単一の表現バリアントしかありません。)

5 ビット値 25、26、27 は、それぞれ 16 ビット、32 ビット、64 ビットの IEEE 754 バイナリ浮動小数点値 [IEEE754] のためのものです。これらの浮動小数点値は、 適切なサイズの追加バイトにエンコードされます。(16 ビット 浮動小数点数に関する情報については、 付録 D を参照してください。)

3.4. 項目のタグ付け

CBOR では、データ項目をタグで囲むことで、 タグ番号によって一意に識別される追加の意味を付与できます。 タグはメジャータイプ 6 であり、その引数(セクション 3)は タグ番号を示し、単一の包含データ項目である タグ内容を含みます。 (タグの内容に追加の構造が必要な場合、この構造は 包含されるデータ項目によって提供されます。) タグ番号とタグ内容の両方から構成されるデータ項目全体を タグと呼びます。タグ内容は、タグ付けされるデータ項目です。

たとえば、長さ 12 のバイト文字列が、 符号なし多倍長整数であることを示す番号 2 のタグ(セクション 3.4.3)でマークされているとします。 エンコードされたデータ項目は、バイト 0b110_00010(メジャータイプ 6、タグ番号を表す追加情報 2)で始まり、その後に、 エンコードされたタグ内容 0b010_01100(メジャータイプ 2、長さを表す追加情報 12)、さらに多倍長整数の 12 バイトが続きます。

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

タグ定義は通常、そのタグに対してどの入れ子のデータ項目が 妥当であるかを定義します。タグ定義は、この 文書で定義されているタグのように、その内容を非常に特定の構文構造に 制限することも、より意味論的に内容を定義することもできます。後者の 例として、タグ 40 と 1040 が配列の複数の表現方法を 受け入れる方法があります [RFC8746]。

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

デコーダーはすべてのタグ番号のタグを理解する必要はありません。また、 特定の CBOR データ項目を作成する実装と、そのストリームをデコードする実装が、 データフロー内の各項目の意味論的な意味を知っているアプリケーションでは、 タグの価値はほとんどない場合があります。この仕様におけるタグの主な 目的は、日付などの共通データ型を定義することです。二次的な目的は、 CBOR データ項目を異なる 形式に変換する必要があると予測され、その項目の内容に関するヒントが必要な場合に、 変換ヒントを提供することです。 タグの意味を理解することは デコーダーにとって任意です。デコーダーは、タグの追加の 意味を解釈せず、単にタグ番号と タグ内容の両方をアプリケーションに提示できます。

タグは、それが囲むデータ項目に意味を適用します。 タグは入れ子にできます。タグ A がタグ B を囲み、そのタグ B がデータ項目 C を囲む場合、 タグ A は、タグ B をデータ項目 C に適用した結果に適用されます。

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 バイト文字列 符号なし多倍長整数。セクション 3.4.3 を参照
3 バイト文字列 負の多倍長整数。セクション 3.4.3 を参照
4 配列 10進小数。セクション 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 エンコーダー/デコーダーの上に実装できないことを意味します(汎用エンコーダー/デコーダーは、 データモデルレベルにおけるマップのエントリのシリアライゼーション順序を 反映しない場合があり、その逆もあります)。したがって、その 実装は通常、 汎用エンコーダー/デコーダーに統合する必要があります。この 特性を持つ新しいタグの定義は推奨されません。

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

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

3.4.1. 標準 日付/時刻文字列

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

3.4.2. エポックベースの 日付/時刻

タグ番号 1 には、UTC 時間の 1970-01-01T00:00Z から、表される市民時刻上の時点までの 秒数を数える数値が含まれます。

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

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

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

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

日付/時刻用のプラットフォーム型には null または undefined の値が含まれる場合があり、これらはアプリケーションプロトコルレベルでも望ましい場合があります。 非有限のタグ内容値を持つタグ番号 1 の値を出力すること (たとえば、未定義の日付/時刻値に NaN を使用したり、設定されていない 有効期限に Infinity を使用したりすること)は、これを扱う明白な方法に見えるかもしれませんが、 タグなしの null または undefined を使用すれば非有限値の使用を避けられ、 エンコーディングも短くなります。 アプリケーションプロトコル設計者は、これらのケースを考慮し、 その処理に関する明確なガイドラインを含めることが推奨されます。

3.4.3. 多倍長整数

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

多倍長整数はバイト文字列データ項目としてエンコードされ、 ネットワークバイトオーダーの符号なし整数 n として解釈されます。その他の型の包含項目は 無効です。タグ番号 2 の場合、 多倍長整数の値は n です。タグ番号 3 の場合、多倍長整数の値は -1 - n です。バイト文字列の推奨シリアライゼーションでは、 先行ゼロをすべて省略します(これは、n = 0 の推奨シリアライゼーションが 空のバイト文字列であることを意味しますが、以下も参照してください)。 これらのタグを理解するデコーダーは、先行ゼロを持つ 多倍長整数もデコードできなければなりません。 メジャータイプ 0 または 1 を使用して表現できる整数の推奨シリアライゼーションでは、 多倍長整数としてではなく、その方法でエンコードします (これは、推奨シリアライゼーションを使用する場合、 空文字列が多倍長整数に現れないことを意味します)。 これは、数値をエンコードする際に基本整数ではなく多倍長整数 表現を選択する非推奨の選択には、 アプリケーション上の意味を持たせる意図がないことを意味します(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. 10進 小数と Bigfloat

タグ番号 4 を使用するプロトコルは、m*(10e) の形式の 任意長の10進小数を表すデータ項目によって汎用データモデルを拡張します。 タグ番号 5 を使用するプロトコルは、m*(2e) の形式の 任意長の2進小数を表すデータ項目によって汎用データモデルを拡張します。 多倍長整数の場合と同様に、 異なる型の値は汎用データモデルでは等しくありません。

10進小数は、整数の仮数と 10 を底とするスケーリング 係数を組み合わせます。1.1 のような10進小数の正確な 表現をアプリケーションが必要とする場合に特に有用です。多くの10進小数は 2進浮動小数点表現では正確に 表現できないためです。

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

10進小数または Bigfloat は、 指数 e と仮数 m というちょうど 2 つの整数を含むタグ付き配列として表現されます。 10進小数(タグ番号 4)は 10 を底とする指数を使用し、 10進小数データ項目の値は m*(10e) です。Bigfloat(タグ番号 5)は 2 を底とする指数を使用し、Bigfloat データ項目の値は m*(2e) です。 指数 e はメジャータイプ 0 または 1 の整数で表現しなければならず、 仮数は多倍長整数(セクション 3.4.3)でもかまいません。その他の構造を持つ包含 項目は無効です。

10進小数の例として、数値 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

10進小数と Bigfloat には、 Infinity、 -Infinity、または NaN の表現はありません。10進小数 または 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-to-JSON コンバーターで後に行われることが期待されるエンコーディング

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

タグ付けされるデータ項目は、バイト文字列でも他の任意の データ項目でもかまいません。 後者の場合、このタグは、そのデータ項目内に 含まれるすべてのバイト文字列データ項目に適用されます。ただし、 期待される変換でタグ付けされた入れ子の データ項目内に含まれるものは除きます。

これら 3 つのタグ番号は、 [RFC4648] で定義されている 3 種類の基本データエンコーディングへの変換を示唆します。 タグ番号 21 は、パディングを使用しない base64url エンコーディング (セクション 5 of [RFC4648]) への変換を示唆します( セクション 3.2 of [RFC4648] を参照)。 すなわち、末尾のすべての等号(「=」)をエンコード済み文字列から削除します。 タグ番号 22 は、RFC 4648 で定義されたパディングを使用する 古典的な base64 エンコーディング (セクション 4 of [RFC4648]) への変換を示唆します。 base64url と base64 の両方で、パディングビットは 0 に設定されます( セクション 3.5 of [RFC4648] を参照)。 また、代替エンコーディングへの変換は バイト文字列の内容に対して行われます(つまり、改行、空白、または その他の追加文字を一切追加しません)。タグ番号 23 は、 大文字の英字を使用する base16(16進)エンコーディングへの変換を示唆します( セクション 8 of [RFC4648] を参照)。 3 つのタグ番号すべてについて、 空のバイト文字列のエンコーディングは空のテキスト文字列であることに注意してください。

3.4.5.3. エンコードされたテキスト

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

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

    • エンコード済みテキスト文字列に アルファベット外の文字が含まれているか、最後の 4 文字のブロックに アルファベット文字が 1 文字しかない場合(アルファベットは、タグ番号 33 については セクション 5 of [RFC4648]、タグ番号 34 については セクション 4 of [RFC4648] で定義)、または
    • 2 文字または 3 文字の ブロックのパディングビットが 0 でない場合、または
    • base64 エンコーディングの パディング文字数が誤っている場合、または
    • base64url エンコーディングに パディング文字が含まれている場合、

    その文字列は無効です。

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

タグ番号 33 と 34 は 21 と 22 とは異なり、 前者ではデータが base エンコードされた形式で転送され、後者では生のバイト文字列 形式で転送されることに注意してください。

[RFC7049] では、Perl Compatible Regular Expressions (PCRE/PCRE2) 形式 [PCRE] または JavaScript 正規表現構文 [ECMA262] の正規表現用に、タグ番号 35 も定義されていました。 これらの正規表現仕様の技術水準は その後進展し、継続的に進展しているため、この 仕様では参照を更新しようとはしません。 代わりに、このタグは([RFC7049] で登録されたとおり)、 使用する特定の正規表現バリアントを帯域外で指定する アプリケーションで引き続き利用できます(場合によっては、 PCRE と ECMA262 の両方に共通する定義済み 部分集合に使用を限定することによって)。 この仕様では、 [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(10 億)未満の整数しか想定されない場合、 デコーダーは整数の 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 エンコーディングは、次の制限を 満たす場合、「中核となる決定論的エンコーディング 要件」を満たします。

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

    • 0 から 23、および -1 から -24 は、 メジャータイプと同じバイト内で表現しなければなりません。
    • 24 から 255、および -25 から -256 は、 追加の uint8_t のみで表現しなければなりません。
    • 256 から 65535、および -257 から -65536 は、 追加の uint16_t のみで表現しなければなりません。
    • 65536 から 4294967295、および -65537 から -4294967296 は、追加の uint32_t のみで 表現しなければなりません。

    浮動小数点値も、その値を保持する最短形式を 使用しなければなりません。たとえば、1.5 は 0xf93e00 (binary16)、 1000000.5 は 0xfa49742408 (binary32) としてエンコードされます。 (これを実装する 1 つの方法は、すべての浮動小数点数を 64 ビット float として開始し、その後 32 ビット float への試験変換を行うことです。結果が 同じ数値であれば、より短い形式を使用し、 16 ビット float への試験変換でも同じ処理を繰り返します。これは、正と負の Infinity に対して 16 ビット float を選択する場合にも機能します。)

  • 不定長項目は現れてはなりません。代わりに 定長項目としてエンコードできます。
  • 各マップのキーは、その決定論的 エンコーディングのバイト単位の辞書順で ソートしなければなりません。たとえば、次のキーは正しくソートされています。

    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 数値形式において 可能な最低の指数を持つ 0 でない数値)は、一部の浮動小数点実装では 出力時にゼロへ切り捨てられたり、 入力時にゼロとして扱われたりする場合があります。 プロトコルの決定論的エンコーディングでは、非正規数を交換から除外して 代わりにゼロを交換することにより、他の 実装に負担を課しつつ、そのような実装に明示的に対応したい場合があります。
  • 同じ数値を、 異なる10進小数、異なる Bigfloat、および 数値を表現するために定義され得る他のタグの異なる形式で表現できます。実装によっては、 これらの形式(または基本的な汎用データモデル内の形式)のいずれかが 等価であるかどうかを常に判定することが現実的でない場合があります。数値の 表現形式についてこの種の選択肢を提供するアプリケーションプロトコルは、 決定論的エンコーディングの形式をどのように選択するかについて明示する必要があります。

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

中核となる決定論的エンコーディング要件(セクション 4.2.1)では、マップキーを セクション 3.9 of [RFC7049] で提案された順序 (そこでは「Canonical CBOR」と呼ばれています)とは異なる順序でソートします。 [RFC7049] で指定された順序との 互換性が必要なプロトコルは、代わりに この仕様の「長さ優先の中核となる決定論的エンコーディング 要件」に基づいて指定できます。

CBOR エンコーディングは、中核となる決定論的エンコーディング要件を満たし、 ただし各マップのキーが次のようにソートされなければならない点だけが異なる場合、 「長さ優先の中核となる決定論的 エンコーディング 要件」を満たします。

  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 の具体的な設計目標の 1 つは、 含まれる、または想定されるスキーマを一切 必要としないことです。デコーダーは CBOR 項目を受け取り、 他の知識なしにデコードできます。

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

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

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

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

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

データ項目を構成するすべてのバイトが 直ちにデコーダーから利用可能であるとは限りません。一部のデコーダーは、 完全なデータ項目をアプリケーションに提示できるまで追加データを バッファリングします。他の デコーダーは、すでにデコードできた入れ子のデータ項目や、 まだ完全には到着していないバイト文字列の一部分など、 トップレベルデータ項目に関する部分的な情報をアプリケーションへ提示できます。 このようなアプリケーションは、アプリケーションに提示される増分データに対して 必要な保護を利用できる、対応するストリーミングセキュリティ メカニズムも備えなければなりません。

一部のアプリケーションやプロトコルでは、 不定長エンコーディングを使用したくない場合があることに注意してください。不定長エンコーディングを使用すると、 エンコーダーはカウントのためにすべてのデータをマーシャリングする必要がなくなりますが、 デコーダーは項目の終端を待つ間、増え続ける量のメモリを 割り当てる必要があります。これは一部の アプリケーションでは問題ない場合がありますが、他ではそうではありません。

5.2. 汎用エンコーダーと デコーダー

汎用 CBOR デコーダーは、すべての整形式のエンコード済み CBOR データ項目をデコードし、 データ項目をアプリケーションへ提示できます。付録 C を参照してください。 (診断表記 セクション 8 は、 整形式の CBOR 値を人間に 提示するために使用できます。)

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

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

5.3. 項目の妥当性

整形式ではあるが無効な CBOR データ項目(セクション 1.2)は、 CBOR データモデルにおいてその中にエンコードされたデータを 解釈する際に問題を引き起こします。 CBOR ベースのプロトコルは複数の層で指定される場合があり、その 下位層では、転送する CBOR データの一部の意味を処理しません。 これらの層は、処理しないデータの妥当性エラーを認識できないため、 そのデータをそのまま転送しなければなりません。無効な CBOR 項目の意味を 初めて処理する層は、次の 2 つの選択肢のいずれかを 選択しなければなりません。

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

CBOR ベースのプロトコルは、デコーダーが遭遇し得る無効項目の各種類について、 これらの選択肢のどちらを採用するかを指定しなければなりません。

このような問題は、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)は、 どの型のデータ項目をタグ内容として 使用することになっているかを指定します。たとえば、符号なしまたは負の 多倍長整数用のタグ番号は バイト文字列に付与することになっています。タグ付きデータ項目を ネイティブ表現(この例ではネイティブ多倍長整数)へデコードするデコーダーは、 タグ付けされているデータ項目の型を検査することが期待されます。 そのようなネイティブ表現を環境で利用できない デコーダーであっても、既知のタグについて検査を行い、 適切に反応する場合があります。
タグ内容として許容されない値:
データ項目の型はタグ内容として許容されていても、 特定の値は許容されない場合があります。たとえば、「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 有効ビットを超える整数をデコードすると 精度が暗黙のうちに失われる可能性があります。 もう 1 つの例として、CBOR は整数 表現の符号ビットをメジャータイプに保持するため、特定の長さの符号付き 数値に対して、同じ長さの一般的なプラットフォーム符号付き整数表現より 1 ビット多く使用できます(たとえば、1+8 バイト 整数では -264..264-1、8 バイト int64_t では -263..263-1)。 数値を使用するプロトコルは、 デコーダーおよび受信アプリケーションにおける 単純でない数値の処理について期待事項を定義すべきです。

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

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

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

5.6. マップのキーの 指定

エンコード側とデコード側のアプリケーションは、 マップでどの型のキーを使用するかについて合意する必要があります。 JSON ベースのアプリケーションと相互運用する必要があるアプリケーションでは、 キーをテキスト文字列だけに制限すると変換が簡単になります。そうしない場合、 他の CBOR 型からテキスト文字列への指定された マッピングが必要になり、これは 実装エラーにつながることがよくあります。キーが本質的に 数値であり、キーの数値順序がアプリケーションにとって重要な場合、 数値をキーとして直接使用すると便利です。

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

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

CBOR ベースのプロトコルは、受信アプリケーションが マップ内に複数の同一キーを見つけた場合に何を行うかを定義しなければなりません。 プロトコル内の結果として得られる規則は CBOR データモデルを尊重しなければなりません。つまり、 マップ内に同一キーが存在することが不正なマップを示し、 デコーダーがエラーで停止しなければならないという規則を設ける場合を除き、 同一キーを持つエントリの特定の処理方法を規定することはできません。 重複キーを持つエントリを含むマップを処理する際、汎用 デコーダーは次のいずれかを行う場合があります。

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

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

マップの CBOR データモデルでは、 マップ表現内のキー/値ペアの順序に意味を帰属させることはできません。したがって、 CBOR ベースのプロトコルは、決定論的 エンコーディング(セクション 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 ベースのプロトコルでは、包含する データ項目の残りを損なうことなくエンコードできるようにするため、 エンコーダーがエンコーディング上の問題を持つデータ項目の代替として、 単純値(セクション 3.3)の undefined を使用する場合があります。

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

このセクションでは、CBOR と JSON の間で変換するための非規範的な助言を示します。コンバーターの実装は、 ここにある助言のうち望むものを使用できます。

JSON テキストは文字のシーケンスであり、 エンコードされたバイト列ではない一方、CBOR データ項目は 文字ではなくバイトで構成されることに注意する価値があります。

6.1. CBOR から JSON への変換

CBOR の型の大部分には、JSON に直接対応するものがあります。しかし、 一部には対応するものがなく、CBOR-to-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 文字列へ変換する場合もあります (たとえば、整数をその10進表現を含む文字列へ 変換することによって)。 ただし、そうするとキー衝突の危険が生じます。 また、以下で提案するように 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、これまでに説明していない 任意の追加情報 値)は、代替値で表現されます。
  • 多倍長整数(メジャータイプ 6、タグ番号 2 または 3)は、 そのバイト文字列をパディングなしの base64url でエンコードして表現され、 JSON 文字列になります。タグ番号 3(負の多倍長整数)の場合、base エンコード済み値の前に 「~」(ASCII チルダ) が挿入されます。(数値ではなくバイナリ blob へ変換するのは、 JSON デコーダーで発生する可能性が高い数値オーバーフローを防ぐためです。)
  • エンコーディングヒントを持つバイト文字列(メジャータイプ 6、タグ 番号 21 から 23)は、ヒントで説明されたようにエンコードされ、JSON 文字列になります。
  • その他のすべてのタグ(メジャータイプ 6、その他の任意のタグ 番号)では、タグ 内容が JSON 値として表現され、タグ番号は無視されます。
  • 不定長項目は変換前に 定長にされます。

CBOR-to-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 が提供する精度に基づいて 10進数から2進数への変換を行います。 JSON 数値の数学的値は、[IEEE754] のセクション 4.3.1 の roundTiesToEven 手順を使用して binary64 へ変換されます。 その後、CBOR へ エンコードする際、推奨シリアライゼーションでは、この変換結果を正確に表現する 最短の浮動小数点 表現を使用します。たとえば、1.5 は 16 ビット浮動小数点値で表現されます (ただし、すべての実装が 最小形式を効率よく見つけられるとは限りません)。デフォルトの binary64 精度を使用する代わりに、変換の 精度に実装定義の制限を設け、表現される値の精度に 影響を与える場合があります。10進表現は、 プロトコルで指定されている場合にのみ CBOR 側で使用すべきです。

CBOR は一般に JSON よりコンパクトなエンコーディングを 提供するよう設計されています。思い浮かぶ実装戦略の 1 つは、 単一のバッファ内で JSON-to-CBOR エンコーディングをインプレースで行うことです。この 戦略では、エスケープがまったくない、または非常に少なく、 255 バイトより長い(またははるかに長い)一部の文字列が、 CBOR の UTF-8 文字列としてエンコードされると拡大する場合があるなど、 多数の病的な ケースを慎重に検討する必要があります。同様に、一部のバイナリ 浮動小数点表現は、JSON の短い 10進表現(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 バイト(「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 は、 この文とまったく同じように記述します(これは JSON では許可されませんが、 JavaScript で記述できる方法でもあります)。タグは、 タグ番号を整数として記述し、その後に括弧内のタグ内容を続けます。たとえば、 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 を示します。

ここで定義した診断表記に対する多数の有用な拡張が、 付録 G of [RFC8610] の「Extended Diagnostic Notation」 (EDN) で提供されています。 同様に、この表記は別の文書で拡張して、 この文書では扱わない NaN ペイロードを文書化できるでしょう。

8.1. エンコーディング標識

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

エンコーディング標識の慣例では、 アンダースコアで始まり、その後に続く英数字または アンダースコアのすべての文字がエンコーディング標識となり、この情報に 関心がない者は無視できます。たとえば、_ または _3。 エンコーディング標識は常に 任意です。

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

アンダースコアの後に10進数字 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 単純値 レジストリ

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 タグレジストリ

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. メディアタイプレジストリ

単一のエンコードされた CBOR データ 項目用のインターネットメディアタイプ [RFC6838](「MIME type」)は、「Media Types」レジストリ [IANA.media-types] で定義される "application/cbor" です。

タイプ名:
application
サブタイプ名:
cbor
必須パラメーター:
該当なし
任意パラメーター:
該当なし
エンコーディングに関する考慮事項:
バイナリ
セキュリティに関する考慮事項:
RFC 8949 の セクション 10 を参照してください。
相互運用性に関する考慮事項:
該当なし
公開された仕様:
RFC 8949
このメディアタイプを使用するアプリケーション:
多数
追加情報:


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

9.4. CoAP Content-Format レジストリ

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

メディアタイプ:
application/cbor
エンコーディング:
-
ID:
60
参照:
RFC 8949

9.5. 構造化構文 サフィックスレジストリ

単一の エンコードされた CBOR データ項目に基づくメディアタイプの構造化構文サフィックス [RFC6838] は +cbor であり、IANA はこれを 「Structured Syntax Suffixes」レジストリ [IANA.structured-suffix] に登録しています。

名前:
簡潔なバイナリオブジェクト表現 (CBOR)
+suffix:
+cbor
参照:
RFC 8949
エンコーディングに関する考慮事項:
CBOR はバイナリ形式です。
相互運用性に関する考慮事項:
該当なし
フラグメント識別子に関する考慮事項:

+cbor に指定されるフラグメント識別子の構文と意味は、 "application/cbor" に指定されるものと同じであるべきです。(RFC 8949 の 公開時点では、"application/cbor" に定義されたフラグメント識別 構文はありません。)

特定の "xxx/yyy+cbor" のフラグメント識別子の構文と意味は、次のように処理すべきです。

  • +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 デコーダーで使用する場合の相互運用性の制限例を示しています。 単一のデータ項目が、このような 制約付きデコーダーと完全なデコーダーの両方によって消費される場合、 コンテンツを挿入または操作できる攻撃者に悪用され得るセキュリティ上の問題につながる可能性があります。

この文書全体で説明しているように、ある状況では 「等価」とみなされ、別の状況では「等価でない」とみなされる値が多数あります。 一例として、数値「1」は 整数または多倍長整数として表現される場合があります。CBOR 入力を解釈するシステムは、 数値「1」についてどちらの形式も受け入れる場合も、一方(または両方)の形式を拒否する場合もあります。このような受け入れ または拒否は、解釈された入力を使用するプログラムに セキュリティ上の影響を及ぼす可能性があります。

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

CBOR デコーダーは、定義上、整形式の CBOR のみを受け入れます。これは 堅牢性を得るための第一歩です。整形式の CBOR ではない入力は、 整形式でないことが検出された時点から それ以上処理されません。可能であれば、この時点までに デコードされたデータが、CBOR デコーダーを使用する アプリケーションに影響を与えるべきではありません。

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

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

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

プロトコルは、 複数の解釈の可能性が確実に 単一の解釈へ縮減されるよう定義すべきです。たとえば、攻撃者は マップ内の重複キーなどの無効な入力を利用したり、数値処理における異なる 精度を悪用して、あるアプリケーションが、 別のアプリケーションで使用される解釈とは異なる解釈に基づいて 判断するよう仕向けたりする可能性があります。一貫した解釈を促進するため、 エンコーダーとデコーダーの実装は、 妥当性検査を行う動作モード (セクション 5.4)を提供すべきです。ただし、汎用デコーダーは、 アプリケーションが入力 データに課すすべての要件を知ることはできません。そのため、アプリケーション自身が 入力検査を行う必要がなくなるわけではありません。また、定義されたタグ番号の集合は 発展するため、アプリケーションは、使用している汎用デコーダーが 妥当性検査をまだサポートしていないタグ番号を使用する可能性があります。したがって汎用 デコーダーは、どのタグ番号を サポートしているか、およびそれらのタグ番号と基本 CBOR (UTF-8 検査、重複マップキー検査)についてどのような妥当性検査を提供するかを文書化する必要があります。

セクション 3.4.3 では、数値をエンコードするために 基本整数ではなく多倍長整数表現を選択する非推奨の選択には、 アプリケーション上の意味を持たせる意図がないと述べていますが、 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, "情報技術 - プログラミング言語 - C", 第4版, ISO/IEC 9899:2018, , <https://www.iso.org/standard/74528.html>.
[Cplusplus20]
International Organization for Standardization, "プログラミング言語 - C++", 第6 版, ISO/IEC DIS 14882, ISO/IEC ISO/IEC JTC1 SC22 WG21 N 4860, , <https://isocpp.org/files/papers/N4860.pdf>.
[IEEE754]
IEEE, "浮動小数点演算に関する IEEE 標準", IEEE Std 754-2019, DOI 10.1109/IEEESTD.2019.8766229, <https://ieeexplore.ieee.org/document/8766229>.
[RFC2045]
Freed, N. and N. Borenstein, "多目的インターネットメール拡張 (MIME) 第1部: インターネット メッセージ本文の形式", RFC 2045, DOI 10.17487/RFC2045, , <https://www.rfc-editor.org/info/rfc2045>.
[RFC2119]
Bradner, S., "RFC で 要求レベルを示すために使用するキーワード", BCP 14, RFC 2119, DOI 10.17487/RFC2119, , <https://www.rfc-editor.org/info/rfc2119>.
[RFC3339]
Klyne, G. and C. Newman, "インターネット上の日付と時刻: タイムスタンプ", RFC 3339, DOI 10.17487/RFC3339, , <https://www.rfc-editor.org/info/rfc3339>.
[RFC3629]
Yergeau, F., "UTF-8、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): 汎用構文", STD 66, RFC 3986, DOI 10.17487/RFC3986, , <https://www.rfc-editor.org/info/rfc3986>.
[RFC4287]
Nottingham, M., Ed. and R. Sayre, Ed., "Atom 配信形式", RFC 4287, DOI 10.17487/RFC4287, , <https://www.rfc-editor.org/info/rfc4287>.
[RFC4648]
Josefsson, S., "Base16、Base32、および Base64 データエンコーディング", RFC 4648, DOI 10.17487/RFC4648, , <https://www.rfc-editor.org/info/rfc4648>.
[RFC8126]
Cotton, M., Leiba, B., and T. Narten, "RFC の IANA に関する考慮事項セクションを記述するためのガイドライン", BCP 26, RFC 8126, DOI 10.17487/RFC8126, , <https://www.rfc-editor.org/info/rfc8126>.
[RFC8174]
Leiba, B., "RFC 2119 のキーワードにおける大文字と 小文字の曖昧さ", BCP 14, RFC 8174, DOI 10.17487/RFC8174, , <https://www.rfc-editor.org/info/rfc8174>.
[TIME_T]
The Open Group, "The Open Group 基本 仕様", セクション 4.16、「エポックからの秒数」, Issue 7、2018年版, IEEE Std 1003.1, , <https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap04.html#tag_04_16>.

11.2. 参考情報

[ASN.1]
International Telecommunication Union, "情報技術 - ASN.1 エンコーディング規則: 基本エンコーディング 規則 (BER)、正準エンコーディング規則 (CER)、および識別エンコーディング規則 (DER) の仕様", ITU-T Recommendation X.690, , <https://www.itu.int/rec/T-REC-X.690-201508-I/en>.
[BSON]
Various, "BSON - バイナリ JSON", <http://bsonspec.org/>.
[CBOR-TAGS]
Bormann, C., "注目すべき CBOR タグ", 作業中, Internet-Draft, draft-bormann-cbor-notable-tags-02, , <https://tools.ietf.org/html/draft-bormann-cbor-notable-tags-02>.
[ECMA262]
Ecma International, "ECMAScript 2020 言語 仕様", 標準 ECMA-262、第11版, , <https://www.ecma-international.org/publications/standards/Ecma-262.htm>.
[Err3764]
RFC Errata, 正誤表 ID 3764, RFC 7049, <https://www.rfc-editor.org/errata/eid3764>.
[Err3770]
RFC Errata, 正誤表 ID 3770, RFC 7049, <https://www.rfc-editor.org/errata/eid3770>.
[Err4294]
RFC Errata, 正誤表 ID 4294, RFC 7049, <https://www.rfc-editor.org/errata/eid4294>.
[Err4409]
RFC Errata, 正誤表 ID 4409, RFC 7049, <https://www.rfc-editor.org/errata/eid4409>.
[Err4963]
RFC Errata, 正誤表 ID 4963, RFC 7049, <https://www.rfc-editor.org/errata/eid4963>.
[Err4964]
RFC Errata, 正誤表 ID 4964, RFC 7049, <https://www.rfc-editor.org/errata/eid4964>.
[Err5434]
RFC Errata, 正誤表 ID 5434, RFC 7049, <https://www.rfc-editor.org/errata/eid5434>.
[Err5763]
RFC Errata, 正誤表 ID 5763, RFC 7049, <https://www.rfc-editor.org/errata/eid5763>.
[Err5917]
RFC Errata, 正誤表 ID 5917, RFC 7049, <https://www.rfc-editor.org/errata/eid5917>.
[IANA.cbor-simple-values]
IANA, "簡潔なバイナリオブジェクト表現 (CBOR) 単純値", <https://www.iana.org/assignments/cbor-simple-values>.
[IANA.cbor-tags]
IANA, "簡潔なバイナリオブジェクト表現 (CBOR) タグ", <https://www.iana.org/assignments/cbor-tags>.
[IANA.core-parameters]
IANA, "制約付き RESTful 環境 (CoRE) パラメーター", <https://www.iana.org/assignments/core-parameters>.
[IANA.media-types]
IANA, "メディアタイプ", <https://www.iana.org/assignments/media-types>.
[IANA.structured-suffix]
IANA, "構造化構文サフィックス", <https://www.iana.org/assignments/media-type-structured-suffix>.
[MessagePack]
Furuhashi, S., "MessagePack", <https://msgpack.org/>.
[PCRE]
Hazel, P., "PCRE - Perl 互換正規 表現", <https://www.pcre.org/>.
[RFC0713]
Haverty, J., "MSDTP-メッセージサービスデータ 伝送プロトコル", RFC 713, DOI 10.17487/RFC0713, , <https://www.rfc-editor.org/info/rfc713>.
[RFC6838]
Freed, N., Klensin, J., and T. Hansen, "メディアタイプの仕様と 登録手順", BCP 13, RFC 6838, DOI 10.17487/RFC6838, , <https://www.rfc-editor.org/info/rfc6838>.
[RFC7049]
Bormann, C. and P. Hoffman, "簡潔なバイナリオブジェクト表現 (CBOR)", RFC 7049, DOI 10.17487/RFC7049, , <https://www.rfc-editor.org/info/rfc7049>.
[RFC7228]
Bormann, C., Ersue, M., and A. Keranen, "制約付き ノードネットワークの用語", RFC 7228, DOI 10.17487/RFC7228, , <https://www.rfc-editor.org/info/rfc7228>.
[RFC7493]
Bray, T., Ed., "I-JSON メッセージ 形式", RFC 7493, DOI 10.17487/RFC7493, , <https://www.rfc-editor.org/info/rfc7493>.
[RFC7991]
Hoffman, P., "「xml2rfc」バージョン 3 語彙", RFC 7991, DOI 10.17487/RFC7991, , <https://www.rfc-editor.org/info/rfc7991>.
[RFC8259]
Bray, T., Ed., "JavaScript Object Notation (JSON) データ交換形式", STD 90, RFC 8259, DOI 10.17487/RFC8259, , <https://www.rfc-editor.org/info/rfc8259>.
[RFC8610]
Birkholz, H., Vigano, C., and C. Bormann, "簡潔なデータ定義 言語 (CDDL): 簡潔なバイナリオブジェクト表現 (CBOR) および JSON データ構造を表現するための表記規則", 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): DNS パケットキャプチャのための形式", RFC 8618, DOI 10.17487/RFC8618, , <https://www.rfc-editor.org/info/rfc8618>.
[RFC8742]
Bormann, C., "簡潔なバイナリオブジェクト 表現 (CBOR) シーケンス", RFC 8742, DOI 10.17487/RFC8742, , <https://www.rfc-editor.org/info/rfc8742>.
[RFC8746]
Bormann, C., Ed., "型付き配列のための簡潔なバイナリオブジェクト 表現 (CBOR) タグ", RFC 8746, DOI 10.17487/RFC8746, , <https://www.rfc-editor.org/info/rfc8746>.
[SIPHASH_LNCS]
Aumasson, J. and D. Bernstein, "SipHash: 高速な短入力 PRF", 暗号学の進展 - 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: 高速な短入力 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]) バージョン 1.2", 第3版, , <https://www.yaml.org/spec/1.2/spec.html>.

付録 A. エンコードされた CBOR データ 項目の例

次の表では、いくつかの CBOR エンコード済み値を16進数 (右列)で、その値の診断表記(左 列)とともに示します。文字列 "\u00fc" は、単一の Unicode 文字 U+00FC (LATIN SMALL LETTER U WITH DIAERESIS, "ü") を含む UTF-8 文字列の診断 表記の一形式であることに注意してください。同様に、"\u6c34" は、 単一の文字 U+6C34 (CJK UNIFIED IDEOGRAPH-6C34, "水") を含む診断表記の UTF-8 文字列であり、 しばしば「水」を表します。また、"\ud800\udd51" は、 単一の文字 U+10151 (GREEK ACROPHONIC ATTIC FIFTY STATERS, "𐅑") を含む診断表記の UTF-8 文字列です。(これらすべての単一文字 文字列は、ASCII のみの仕様が必要でない限り、 診断表記内でネイティブ UTF-8 によって表現することもできます。) 多倍長整数について示す診断表記では、 その意図された数値を、タグ付きバイト文字列( 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 符号なし多倍長整数(データ項目「バイト文字列」が 後続)
0xc3 負の多倍長整数(データ項目「バイト文字列」が 後続)
0xc4 10進小数(データ項目「配列」が後続。 セクション 3.4.4 を参照)
0xc5 Bigfloat(データ項目「配列」が後続。セクション 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; // バイト/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(); // 不正な単純値
  }
  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 を通知
      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. 半精度

半精度浮動小数点数が IEEE 754 に追加されたのは 2008 年になってからであるため [IEEE754]、現在のプログラミングプラットフォームでも それらのサポートは限定的であることがよくあります。このようなサポートがなくても、少なくともデコード サポートを含めることは非常に簡単です。C 言語による半精度浮動小数点数の 小さなデコーダーの例を 図 3 に示します。Python の同様のプログラムは 図 4 にあります。このコードは、2 バイト値がすでに ネットワークバイトオーダーの(unsigned 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 プロトコルは、ほとんど(あるいはまったく)ありません。その理由は多数考えられますが、 よく挙げられる理由の 1 つは、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 は整数と浮動小数点 値を区別していません(また、後者は形式上10進数です)。CBOR は 数値の2進表現を提供し、整数と 浮動小数点値で異なります。実装と使用の経験から、これら 2 つの数値 領域の分離を文書内でより明確にする必要があることが示唆されました。そのため、 整数が浮動小数点 値の代わりにシームレスに使用できることを示唆する表現は削除されました。また、JSON を CBOR に変換するときのこれらの型の扱いについて (I-JSON [RFC7493] に基づく)提案が追加され、 特定の丸め機構の使用が推奨されました。

データモデル内の 1 つの値に対して、CBOR は複数の エンコーディングの選択肢を提供することがよくあります。新しいセクション(セクション 4)では、 「推奨シリアライゼーション」(セクション 4.1)という用語を導入し、 さまざまな種類のデータ項目について定義しています。この用語に基づき、このセクションでは CBOR ベースのプロトコルが「決定論的 エンコーディング」(セクション 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 の定義に 基づく登録は引き続き有効です。

「argument」と「head」について、 セクション 3 に用語が導入され、 以降の議論が簡潔になりました。

セキュリティに関する考慮事項(セクション 10)は 大部分が書き直され、大幅に 拡充されました。また、文書内の複数の箇所で、 デコーダーが整形式性エラーを単純に容認してはならないことが、より明確に示されています。

謝辞

CBOR は MessagePack から着想を得ました。MessagePack は Sadayuki Furuhashi ("frsyuki") によって開発され、普及が進められました。この MessagePack への言及は帰属表示のみを目的としています。CBOR は 設計目標と要件が異なるため、MessagePack の バージョンまたは代替を意図したものではありません。

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

CBOR の追加情報のエンコーディングは、 CoAP のために Klaus Hartke が設計した長さ情報の エンコーディングから着想を得ました。

この文書には、多くの人々による提案も取り入れられています。 特に Dan Frost、James Manger、 Jeffrey Yasskin、Joe Hildebrand、 Keith Moore、Laurence Lundblade、 Matthew Lepinski、Michael Richardson、 Nico Williams、Peter Occil、 Phillip Hallam-Baker、Ray Polk、 Stuart Cheshire、Tim Bray、 Tony Finch、Tony Hansen、および Yaron Sheffer です。Benjamin Kaduk は IESG の処理中に広範なレビューを提供しました。 Éric Vyncke、Erik Kline、 Robert Wilton、および Roman Danyliw は、 Eve Schooler による IoT directorate のレビューを含む、 さらなる IESG コメントを提供しました。

著者の連絡先

Carsten Bormann
Universität Bremen TZI
Postfach 330440
D-28359 Bremen
ドイツ
Paul Hoffman
ICANN