任务架构

Android CBOR 解码契约:Tag、重复键与确定性编码

按 RFC 8949 generic data model 定义 map key 相等、duplicate、tag 和 deterministic profile;区别 Protobuf/ProtoJSON,不把格式校验当认证或授权。

审核状态: 内容已校验;中文稿供用户审核 · 2026-10-08 · Fact IDs: ANDROID-CBOR-MAP-TAGS-2026-10, ANDROID-PRIVACY-01, PRIVACY-01

直接回答

CBOR 是二进制数据互换格式,其 generic data model 包含无符号/负整数、byte string、text string、array、map、tag、simple value 和浮点值。不能在判断原始类型区别是否重要之前,就把所有 item 扁平转换成 JSON。Generic model 中整数与浮点数即使数值相同仍是不同类型;byte string 与 text string 不同;tagged value 与其未加 tag 内容也不同。JSON object 无法直接表示全部差异。 RFC 8949 区分 well-formedness、validity 和 application expectation。Well-formedness 判断字节是否可解析为 CBOR item;validity 再检查 duplicate key、tag 限制等条件;expected input 还取决于应用 schema、允许 tag、key type、范围和操作。字节结构可解析,但仍可能违反 validity profile 或应用不支持。应分别报告状态;“decode 成功”不等于“数据已接受”。 Map duplicate 检查必须按选定 data model 执行,不能靠非正式数学直觉。Generic model 中 integer `1` 与 float `1.0` 是不同 key;正零与负零在 key equivalence 中相等。两个 NaN 的 significand 向右补零扩至 64 位后相同,才按 RFC 等价。带 tag/不带 tag、byte string/text string 也各有区别。协议可另定义等价;之后把 key 转为语言 Map 或 JSON object 时仍可能产生原始 generic CBOR 中不存在的投影碰撞,两层应分开测试。 Decoder 对重复键的处理并不一致:可能拒绝、把全部 pair 交给应用,或只保留一个值。Streaming decoder 也可能没有足够 map 状态检测重复。如果安全或确定性解释依赖重复检测,就要用能暴露所有 pair 或在 map collapse 前拒绝重复的 API。如果 decoder 已经只保留第一个或最后一个,应用可能无法发现哪些值被丢掉。记录准确 decoder 行为;不满足协议时拒绝含糊输入。 Tag 用数值 tag number 和包裹的 data item 携带语义。RFC 8949 定义通用 tag 结构,但不为每个注册或私有 tag 指定应用含义。明确哪些 tag 认识、未知 tag 是拒绝还是不透明保留,以及已知 tag 的结构/语义校验。确定日期时间、大数、URI 或应用值是否依赖 tag 后才能考虑投影;不能先删 tag。只有 tag number 不能证明内容符合预期形式或语义。 Deterministic encoding 是协议 profile,不是认证功能,也不是一个适用于所有协议的唯一“canonical CBOR”字节串。RFC 8949 core deterministic requirements 约束 preferred serialization、长度、浮点宽度、定长 item 和 map-key 顺序;协议还能为 tag 是否存在和应用区别添加规则。必须声明采用哪些要求。对有效但非 deterministic 的 item 重新编码时,即使语义值保留,字节也可能变化。除非签名/哈希协议明确表示 profile,否则不能对原始 bytes 签名后再用重编码 bytes 比较。 CBOR 转 JSON 通常是有损投影,除非应用定义可保留 tag 的 wrapper。JSON object key 只能是 string,将整数或复合 CBOR key 转字符串会冲突。JSON number 也无法保留每个 CBOR integer、浮点宽度、非有限值或负零差异。Byte string 需要明确表示法,例如 base64;tag 需要能保留 number 和内容的表示。若 consumer 不能接收原始 model,就保留 CBOR bytes 并明确标记展示视图,不能声称透明互转。 根据 RFC vectors 和应用规则构建夹具:数学值相同的 integer/float key、正负零、significand 向右补零扩到 64 位后相同的 NaN、字节相同的 byte/text key、带/不带 tag、完全重复 key、已知/未知 tag、不支持的 tag 内容、indefinite-length item、非 preferred 整数/浮点宽度、非法 UTF-8、截断数据、深层容器和超大 byte string。分别检查 parser、duplicate、tag policy、validity 与应用投影。 后续处理之前设资源上限:输入总字节、嵌套深度、map/array 项目数、byte/text 长度、tag 嵌套和耗时。优先用所选 decoder 的限制能力,并用恶意合成 fixture 验证。不能编造 library 默认值,也不要因为缺少一个控制项就自写 CBOR parser。若解析 API 无法暴露合同需要的重复 pair 或未知 tag,应将该用法标为不支持或换用具备所需 API 的库。 最终报告列出 RFC profile、decoder 坐标/版本、重复键行为、支持 tag、deterministic profile、generic-model validity、应用校验及每一步转换。区分格式错误、invalid map/tag、valid-but-unsupported 和应用接受值。本文是 CBOR 互通方法,不表示 Cove 使用 CBOR、generic tag 自动可信或确定性编码可以认证数据。

JSON 投影合并了带类型的 CBOR key

源 CBOR map 含 integer key `1` 与 float key `1.0`;按 RFC 8949 generic data model,它们是不同 key,不构成重复。后续 JSON converter 把二者都转成字符串 `"1"`,而保留 typed pair 的 consumer 可以区分它们,或拒绝该投影。

决策

先按 generic CBOR 等价规则检查源 duplicate,再单独测试目标语言/JSON key 投影;两个源 key 合并时拒绝该投影。

预期结果

导入器区分合法 typed CBOR map 与有损或冲突投影,并报告投影层失败,不将原 map 标为无效。

需要收集的证据

只有将以下证据与同一模型文件和测试运行关联起来,结论才可复核:

  • ANDROID-CBOR-MAP-TAGS-2026-10:RFC 8949 区分 well-formedness、validity 与应用期望;generic map-key 等价将整数与浮点区分、将正负零视为相等,并按 significand 定义 NaN 等价。
  • ANDROID-PRIVACY-01:解析成功不能取代应用的访问、存储和用户控制策略。
  • PRIVACY-01:端侧推理不证明应用无其他网络请求;CBOR 确定性编码也不建立此类边界。

任务质量需要有版本记录的语料和验收规则;流畅的单条样例不等于准确度结果。

实施流程

  1. 固定 decoder 与 data-model profile. 记录准确 Android decoder/version、RFC 8949 profile、map 表示、tag callback、streaming 模式和 parser 资源控制。确认原生 map 合并前是否还能观察每个键值 pair。
  2. 规定 key 等价和 duplicate 结果. 按 RFC 8949 generic key equivalence:integer `1` 与 float `1.0` 不同;signed zero 相等;significand 右补零扩至 64 位后相同的 NaN 等价。按规范区分 tagged/untagged 与 byte/text,再单独测试 host-language/JSON 投影碰撞。
  3. 定义支持 tag 与未知 tag 行为. 按 tag number allowlist,并校验要求的内容类型和语义。只有应用能保留 tag number 与 item 时才可不透明保留未知 tag,否则拒绝。检查其含义前不得先删除 tag。
  4. 选定确定性编码 profile. 命名采用的 RFC deterministic 要求和 tag、浮点、负零、map 顺序、key type 等协议补充规则。语义 item 与编码字节分开比较;deterministic encoding 不是完整性或认证。
  5. 测试 validity、转换和资源限制. 用 RFC 与合成 fixture 测重复键、未知 tag、数字边界、byte/text 碰撞、损坏/截断输入、深度、项数和 decoder limits。分别报告 well-formed、valid、expected、unsupported 与 rejected。

让每个阶段的状态都可观察。失败信息应指出阶段、模型、运行时和恢复动作,同时避免记录用户私密内容。

验收标准

  • CBOR well-formedness、RFC/profile validity 和应用期望值分开报告,不把 parse 成功等同接受。
  • 重复键依 RFC 8949 §5.6.1 generic key equivalence 检查;其中 integer `1` 与 float `1.0` 不同,signed zero 和 NaN 遵循规范等价规则。
  • 准确 library/version 上测试 decoder duplicate 行为、pair 可见性、tag allowlist/unknown-tag policy 与应用投影碰撞。
  • 确定性编码 profile 有名称与范围;不将它称为加密完整性、发送者认证或唯一通用 canonical 字节表示。
  • JSON 投影保留或明示 tag、byte string、数值差异和非字符串 key 的损失;不接受静默字符串 key 强制转换。

决策对照表

维度选择或证据解读方式
CBOR well-formed item解析 major type、长度与嵌套 item。字节结构可解析;仍可能违反 validity 要求或应用 schema。
重复 map key在 map collapse 前按声明 CBOR data model 检查。RFC generic 规则区分 integer 与 float,但正负零等价;host 投影另可能产生碰撞。
已知 tag校验 tag number 与要求的内容类型/语义。Tag 结构有效不能证明内部 item 满足应用要求。
未知 tag按策略不透明保留 number/item 或拒绝。静默删 tag 会抹掉语义并让原本不同的值无法区分。
确定性编码应用具名协议 profile 后再按 profile 比较字节。限制表示选择,不认证内容,也不替代应用校验。
JSON object 投影使用显式 wrapper,或报告不支持的 key/value 区别。字符串 key 和 JSON number 限制可能合并不同 CBOR 值。

需要避免的失败模式

  • 把 integer 1 与 floating-point 1.0 当成 RFC generic model 的重复 key。
  • 忽略 +0.0/-0.0 与 NaN 的 RFC key-equivalence 规则,或将语言 Map/JSON 投影碰撞误称 CBOR duplicate。
  • 把可解析当成 valid/应用期望,把未知 tag 默默删除。
  • 把 deterministic encoding 宣称为签名、完整性认证或唯一通用 canonical bytes。

还要避免静默回退、版本未固定、缺少取消处理,以及把不同配置的结果混在一起下结论。失败运行也应与成功记录一并保存。

最小复现记录

层级记录内容
设备厂商、型号、芯片、内存档位、操作系统版本
软件应用版本和 Git 提交号
模型系列、变体、版本、格式、文件长度、摘要、量化方式
运行时名称、版本、请求后端及实际后端证据
工作负载样例版本、输入摘要、提示词摘要、输出策略
结果完成、失败、取消、回退及保护隐私的诊断信息

发布检查表

  • ☐ 主要搜索问题已回答,且没有未经支持的数字。
  • ☐ 所有模型文件和运行时版本均已固定。
  • ☐ 代表性任务和失败处理策略均有说明。
  • ☐ 生命周期、取消、清理和回退均已测试。
  • ☐ 用户内容与网络边界均有说明。
  • ☐ 结论只适用于被记录的配置。
  • ☐ 新增测试结果时链接到原始方法或证据。

来源与相关证据

中文部署与排错专题见。奇连 AI 端侧专题。

常见问题

CBOR 的 integer key 1 和 floating-point key 1.0 是重复键吗?

按 RFC 8949 generic data model 不是:整数与浮点是不同值,即使数值相同。协议特定模型或后续语言/JSON 转换可能另有等价或碰撞,应分开报告。

CBOR decoder 接受 item,就一定是应用有效输入吗?

不一定。要区分 well-formed 字节、所选 profile 下的 validity,以及应用要求的 tag、key、范围和操作。解析成功后仍可拒绝或标为不支持。

应用可以接受未识别的 CBOR tag 吗?

应用 profile 可以明确选择不透明保留未知 tag;只有确认其语义不影响支持用途时才可选择忽略。Decoder 必须留足信息供策略判断,不能先删 tag。此处描述应用合同,不表示 RFC 8949 一概禁止未知 tag。

确定性 CBOR 能防数据篡改吗?

不能。确定性 profile 只限制表示选择,不提供加密完整性、发送者身份、操作授权,也不能证明解码值符合应用预期。