Skip to main content

1. Introduction (简介)

有数百种用于结构化数据二进制表示的标准化格式 (也称为二进制序列化格式, Binary Serialization Formats). 其中, 一些格式用于特定的信息领域, 而另一些则泛化用于任意数据. 在 IETF 中, 后一类别中最著名的格式可能是 ASN.1 的 BER 和 DER [ASN.1].

本文档定义的格式遵循一些当前格式无法很好满足的特定设计目标. 底层数据模型 (Data Model) 是 JSON 数据模型 [RFC8259] 的扩展版本. 需要注意的是, 这并非提议扩展 RFC 8259 中的语法, 因为这样做会导致与已部署的 JSON 文档产生重大的向后不兼容性. 相反, 本文档只是定义了自己的数据模型, 该模型从 JSON 开始构建.

附录 E 列出了一些现有的二进制格式, 并讨论了它们在多大程度上符合或不符合 Concise Binary Object Representation (CBOR, 简洁二进制对象表示) 的设计目标.

本文档废止 [RFC7049], 提供了编辑改进, 新的细节和勘误修复, 同时保持与 RFC 7049 交换格式的完全兼容性. 它不会创建格式的新版本.

1.1. Objectives (目标)

CBOR 的目标, 大致按重要性递减的顺序排列如下:

  1. 表示必须能够明确编码互联网标准中使用的大多数常见数据格式.

    • 它必须使用二进制编码表示一组合理的基本数据类型和结构. 这里的"合理"主要受 JSON 能力的影响, 并增加了对二进制字节串 (Byte String) 的主要支持. 支持的结构仅限于数组 (Array) 和树 (Tree); 不支持循环 (Loop) 和格状图 (Lattice-Style Graph).

    • 不要求所有数据格式都以唯一方式编码; 也就是说, 数字 "7" 可以用多种不同方式编码是可以接受的.

  2. 编码器 (Encoder) 或解码器 (Decoder) 的代码必须能够紧凑, 以支持内存, 处理器能力和指令集非常有限的系统.

    • 编码器和解码器需要能够用非常少的代码实现 (例如, 在 [RFC7228] 中定义的 1 类受限节点 (Class 1 Constrained Node) 中).

    • 格式应使用当代机器的数据表示 (例如, 不需要二进制到十进制的转换).

  3. 数据必须能够在没有模式描述 (Schema Description) 的情况下解码.

    • 与 JSON 类似, 编码的数据应该是自描述的 (Self-Describing), 以便可以编写通用解码器.
  4. 序列化必须合理紧凑, 但数据紧凑性次于编码器和解码器的代码紧凑性.

    • 这里的"合理"以 JSON 作为大小的上限, 并受实现复杂性的限制, 这限制了可以投入实现该紧凑性的努力. 使用通用压缩方案或大量位操作违反了复杂性目标.
  5. 格式必须适用于受限节点 (Constrained Node) 和高容量应用.

    • 这意味着编码和解码的 CPU 使用必须相当节省. 这对于受限节点和具有大量数据的应用中的潜在使用都是相关的.
  6. 格式必须支持所有 JSON 数据类型以实现与 JSON 之间的转换.

    • 它必须支持合理级别的转换, 只要表示的数据在 JSON 的能力范围内. 必须能够为所有类型的数据定义指向 JSON 的单向映射.
  7. 格式必须是可扩展的, 并且扩展的数据必须能被早期的解码器解码.

    • 该格式设计为可使用数十年.

    • 格式必须支持一种可扩展性形式, 允许回退 (Fallback), 以便不理解扩展的解码器仍然可以解码消息.

    • 格式必须能够在将来由后续的 IETF 标准进行扩展.

1.2. Terminology (术语)

本文档中的关键词 "MUST" (必须), "MUST NOT" (禁止), "REQUIRED" (必需), "SHALL" (应), "SHALL NOT" (不应), "SHOULD" (应该), "SHOULD NOT" (不应该), "RECOMMENDED" (推荐), "NOT RECOMMENDED" (不推荐), "MAY" (可以) 和 "OPTIONAL" (可选) 应按照 BCP 14 [RFC2119] [RFC8174] 中的描述进行解释, 当且仅当它们以全大写形式出现时, 如此处所示.

术语 "byte" (字节) 用于其现在惯用的意义, 作为 "octet" (八位字节) 的同义词. 所有多字节值都以网络字节序 (Network Byte Order) 编码 (即最高有效字节在前, 也称为 "大端序" (Big-Endian)).

本规范使用以下术语:

Data item (数据项): 单个 CBOR 数据片段. 数据项的结构可能包含零个, 一个或多个嵌套的数据项. 该术语既用于表示格式中的数据项, 也用于解码器可以从中派生的抽象概念; 前者可以通过使用术语 "encoded data item" (编码数据项) 来特别指明.

Decoder (解码器): 一个过程, 它解码一个良构的编码 CBOR 数据项并将其提供给应用程序. 正式来说, 解码器包含一个解析器 (Parser), 使用 CBOR 的语法规则分解输入, 以及一个语义处理器 (Semantic Processor), 以应用程序适合的形式准备数据.

Encoder (编码器): 一个过程, 它从应用程序信息生成 CBOR 数据项的 (良构) 表示格式.

Data Stream (数据流): 零个或多个数据项的序列, 不进一步组装成更大的包含数据项 (参见 [RFC8742] 中的一个应用). 构成数据流的独立数据项有时也称为 "top-level data items" (顶层数据项).

Well-formed (良构): 遵循 CBOR 语法结构的数据项. 良构的数据项使用初始字节以及由其值定义的字节串和/或数据项 (如 CBOR 中所定义), 并且不包括后续的无关数据. 根据定义, CBOR 解码器仅从良构的数据项返回内容.

Valid (有效): 既良构又遵循适用于 CBOR 数据项的语义限制 (第 5.3 节) 的数据项.

Expected (预期): 除了其正常的英语含义外, 术语 "expected" 用于描述应用程序对其输入数据的超出 CBOR 有效性的要求. Well-formed (可处理), valid (由有效性检查通用解码器检查) 和 expected (由应用程序检查) 形成了可接受性的分层层次结构.

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 以强调字节中位的所需解释; 在这种情况下, 它被分为 3 位和 5 位. 编码的 CBOR 数据项有时以 "0x" 或 "0b" 表示法给出; 这些值首先按照 C 中的方式解释为数字, 然后按网络字节序解释为字节串, 包括表示法中表达的任何前导零字节.

单词可能用 斜体 表示强调; 在本规范的纯文本形式中, 这通过用下划线字符包围单词来表示. 逐字文本 (例如, 来自编程语言的名称) 可以设置为 "等宽" 类型; 在纯文本中, 这通过用双引号包围文本来近似表示 (双引号也保留其通常含义), 这有些模糊.