1. 简介
用于结构化数据二进制表示的标准化格式有数百种 (也称为二进制序列化格式). 其中一些面向特定信息领域, 另一些则泛化用于任意数据. 在 IETF 中, 后一类中最知名的格式可能是 ASN.1 的 BER 和 DER [ASN.1].
本文定义的格式遵循若干特定设计目标, 而当前格式并不能很好满足这些目标. 其底层数据模型是 JSON 数据模型 [RFC8259] 的扩展版本. 需要注意, 这并不是提议一般性扩展 RFC 8259 中的语法, 因为这样会与已经部署的 JSON 文档产生显著向后不兼容. 相反, 本文档只是定义了自己的数据模型, 该模型从 JSON 出发.
附录 E 列出了一些现有二进制格式, 并讨论它们在多大程度上符合或不符合 Concise Binary Object Representation (CBOR) 的设计目标.
本文档废止 [RFC7049], 在保持与 RFC 7049 交换格式完全兼容的同时, 提供编辑性改进, 新细节以及勘误修正. 它不会创建该格式的新版本.
1.1. 目标
CBOR 的目标按重要性大致递减排列如下:
-
表示形式必须能够无歧义地编码互联网标准中使用的大多数常见数据格式.
-
它必须使用二进制编码表示一组合理的基本数据类型和结构. 这里的 "合理" 很大程度上受 JSON 能力影响, 主要新增的是二进制字节字符串. 支持的结构限于数组和树; 不支持循环和格状图.
-
不要求所有数据格式都唯一编码; 也就是说, 数字 "7" 可以用多种不同方式编码是可以接受的.
-
-
编码器或解码器的代码必须能够足够紧凑, 以支持内存, 处理器能力和指令集都非常受限的系统.
-
编码器和解码器需要能够用非常少量的代码实现 (例如 [RFC7228] 中定义的 class 1 受限节点).
-
该格式应使用当代机器的数据表示 (例如, 不要求二进制到十进制转换).
-
-
数据必须能够在没有模式描述的情况下解码.
- 与 JSON 类似, 编码数据应当是自描述的, 使通用解码器可以编写.
-
序列化必须相当紧凑, 但对编码器和解码器而言, 数据紧凑性次于代码紧凑性.
- 这里的 "合理" 以 JSON 作为大小上界, 并受实现复杂度约束, 后者限制了为实现紧凑性可投入的工作量. 使用通用压缩方案或大量位操作都违反复杂度目标.
-
该格式必须同时适用于受限节点和高容量应用.
- 这意味着它在编码和解码时都必须相当节省 CPU 使用量. 这既与受限节点有关, 也与可能在具有极高数据量的应用中使用有关.
-
该格式必须支持所有 JSON 数据类型, 以便与 JSON 相互转换.
- 只要所表示的数据在 JSON 能力范围内, 它就必须支持合理程度的转换. 必须能够为所有类型的数据定义朝向 JSON 的单向映射.
-
该格式必须可扩展, 并且扩展数据必须能被较早的解码器解码.
-
该格式设计为可使用数十年.
-
该格式必须支持一种允许回退的可扩展形式, 使不理解某个扩展的解码器仍能解码消息.
-
该格式必须能够在未来由后续 IETF 标准扩展.
-
1.2. 术语
本文档中的关键字 "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED", "MAY" 和 "OPTIONAL" 在且仅在以这里所示的全大写形式出现时, 应按 BCP 14 [RFC2119] [RFC8174] 中的说明解释.
术语 "byte" 使用其现在通常含义, 作为 "octet" 的同义词. 所有多字节值都以网络字节序编码 (即最高有效字节在前, 也称为 "big-endian").
本规范使用以下术语:
Data item: 单个 CBOR 数据片段. 一个数据项的结构可以包含零个, 一个或多个嵌套数据项. 该术语既用于表示格式中的数据项, 也用于解码器可从中导出的抽象概念; 前者可以通过使用术语 "encoded data item" 来特别指明.
Decoder: 对格式良好的已编码 CBOR 数据项进行解码, 并使其可供应用使用的过程. 从形式上讲, 解码器包含一个解析器, 用于按 CBOR 语法规则分解输入, 也包含一个语义处理器, 用于把数据准备成适合应用的形式.
Encoder: 从应用信息生成 CBOR 数据项的格式良好表示形式的过程.
Data Stream: 零个或多个数据项的序列, 这些数据项未进一步组装成更大的包含数据项 (一个应用见 [RFC8742]). 构成数据流的独立数据项有时也称为 "top-level data items".
Well-formed: 遵循 CBOR 语法结构的数据项. 格式良好的数据项使用 CBOR 中定义的初始字节以及由其值隐含的字节字符串和/或数据项, 并且不包含后续无关数据. 按定义, CBOR 解码器只会从格式良好的数据项返回内容.
Valid: 格式良好并且还遵循适用于 CBOR 数据项的语义限制的数据项 (第 5.3 节).
Expected: 除普通英语含义外, 术语 "expected" 用于描述应用对其输入数据提出的, 超出 CBOR 有效性的要求. 格式良好 (完全可处理), 有效 (由通用有效性检查解码器检查) 和预期 (由应用检查) 构成可接受性的层级.
Stream decoder: 对数据流进行解码, 并在接收序列中的每个数据项时使其可供应用使用的过程.
浮点值的术语和概念, 例如 Infinity, NaN (not a number), negative zero 和 subnormal, 在 [IEEE754] 中定义.
在解释位算术或数据类型时, 本文档使用 C 编程语言 [C] 中熟悉的记法, 但 ".." 表示包含给定两端的范围, 上标记法表示幂运算. 例如, 2 的 64 次方记为: 2^(64). 在本规范的纯文本版本中, 上标记法不可用, 因而用替代记法呈现. 这种记法没有针对本 RFC 优化; 遗憾的是, 它与 C 的异或存在歧义 (异或只在附录中使用, 而附录又不使用幂运算), 因而要求纯文本版本的读者谨慎理解.
示例和伪代码假定有符号整数使用二进制补码表示, 且有符号整数右移执行符号扩展; 这些假定也在 C++ 2020 版本 (目前可作为最终草案 [Cplusplus20] 获取) 的第 6.8.1 节 (basic.fundamental) 和第 7.6.7 节 (expr.shift) 中指定.
与十六进制数的 "0x" 记法类似, 二进制记法中的数字以前缀 "0b" 表示. 下划线可以仅为可读性加入数字中, 因此 0b00100001 (0x21) 可以写作 0b001_00001, 以强调对该字节中各位的期望解释; 在这种情况下, 它被拆分为三位和五位. 已编码 CBOR 数据项有时以 "0x" 或 "0b" 记法给出; 这些值首先像 C 中那样解释为数字, 然后按网络字节序解释为字节字符串, 包括记法中表达的任何前导零字节.
词语可以使用 italicized 形式表示强调; 在本规范纯文本形式中, 这通过用下划线字符包围词语来表示. 原样文本 (例如来自编程语言的名称) 可以设置为 "monospace" 字体; 在纯文本中, 这会通过用双引号包围文本来近似表示, 但有一定歧义 (双引号也保留其通常含义).