Go语言CBOR编解码库 安全高效功能全面
fxamacker/cbor是符合IETF STD 94标准的Go语言CBOR编解码库。该库提供快速安全的编解码功能,支持CBOR标签、核心确定性编码和重复键检测。通过可配置限制防御恶意输入,并具有简单易用的API。fxamacker/cbor被Arm、Cisco等知名项目采用,是JSON和MessagePack等数据格式的可靠替代方案。
fxamacker/cbor 是一个用于编码和解码 CBOR 和 CBOR 序列 的库。
CBOR 是 JSON、MessagePack、Protocol Buffers 等的可信替代品。CBOR 是由 IETF STD 94 (RFC 8949) 定义的互联网标准,设计目标是在未来数十年内保持相关性。
fxamacker/cbor
被 Arm Ltd.、Cisco、EdgeX Foundry、Flow Foundation、Fraunhofer-AISEC、Kubernetes、Let's Encrypt (ISRG)、Linux Foundation、Microsoft、Mozilla、Oasis Protocol、Tailscale、Teleport 等项目使用。
请参阅快速开始和发布版本。🆕 UnmarshalFirst
和 DiagnoseFirst
可以解码 CBOR 序列。cbor.MarshalToBuffer()
和 UserBufferEncMode
接受用户指定的缓冲区。
fxamacker/cbor
是一个完全符合 IETF STD 94 (RFC 8949) 的 CBOR 编解码器。它还支持 CBOR 序列(RFC 8742)和扩展诊断表示法(RFC 8610 的附录 G)。
特性包括对 CBOR 标签的全面支持、核心确定性编码、重复映射键检测等。
设计平衡了安全性、速度、并发性、编码数据大小、可用性等方面的权衡。
fxamacker/cbor
具有可配置的限制等,可以防御恶意 CBOR 数据。
相比之下,encoding/gob
不设计用于对抗性输入的加固。
fxamacker/cbor
具有可配置的限制等,可以防御恶意 CBOR 数据。
相比之下,encoding/gob
不设计用于对抗性输入的加固。
fxamacker/cbor
在拒绝格式错误的 CBOR 数据方面非常快速。例如,尝试将 10 字节的恶意 CBOR 数据解码为 []byte
(使用默认设置):
编解码器 | 速度 (ns/op) | 内存 | 分配次数 |
---|---|---|---|
fxamacker/cbor 2.5.0 | 44 ± 5% | 32 B/op | 2 allocs/op |
ugorji/go 1.2.11 | 5353261 ± 4% | 67111321 B/op | 13 allocs/op |
最新比较使用: |
[]byte{0x9B, 0x00, 0x00, 0x42, 0xFA, 0x42, 0xFA, 0x42, 0xFA, 0x42}
编解码器 | 速度 (ns/op) | 内存 | 分配次数 |
---|---|---|---|
fxamacker/cbor 2.5.0-beta2 | 44.33 ± 2% | 32 B/op | 2 allocs/op |
fxamacker/cbor 0.1.0 - 2.4.0 | ~44.68 ± 6% | 32 B/op | 2 allocs/op |
ugorji/go 1.2.10 | 5524792.50 ± 3% | 67110491 B/op | 12 allocs/op |
ugorji/go 1.1.0 - 1.2.6 | 💥 运行时: | 内存不足: | 无法分配 |
[]byte{0x9B, 0x00, 0x00, 0x42, 0xFA, 0x42, 0xFA, 0x42, 0xFA, 0x42}
结构体标签(toarray
, keyasint
, omitempty
)可以减少结构体的编码大小。
https://go.dev/play/p/YxwvfPdFQG2
// 示例:编码嵌套结构体(使用omitempty标签) // - encoding/json: 18字节JSON // - fxamacker/cbor: 1字节CBOR package main import ( "encoding/hex" "encoding/json" "fmt" "github.com/fxamacker/cbor/v2" ) type GrandChild struct { Quux int `json:",omitempty"` } type Child struct { Baz int `json:",omitempty"` Qux GrandChild `json:",omitempty"` } type Parent struct { Foo Child `json:",omitempty"` Bar int `json:",omitempty"` } func cb() { results, _ := cbor.Marshal(Parent{}) fmt.Println("hex(CBOR): " + hex.EncodeToString(results)) text, _ := cbor.Diagnose(results) // 诊断表示法 fmt.Println("DN: " + text) } func js() { results, _ := json.Marshal(Parent{}) fmt.Println("hex(JSON): " + hex.EncodeToString(results)) text := string(results) // JSON fmt.Println("JSON: " + text) } func main() { cb() fmt.Println("-------------") js() }
输出结果(DN是诊断表示法):
hex(CBOR): a0
DN: {}
-------------
hex(JSON): 7b22466f6f223a7b22517578223a7b7d7d7d
JSON: {"Foo":{"Qux":{}}}
<hr/>
</details>
<details><summary>使用多个结构体标签的示例</summary><p/>
结构体标签简化了需要使用整数键的CBOR数组或映射的CBOR协议的使用。
CBOR标签在TagSet
中指定。
可以使用TagSet
创建自定义模式来处理CBOR标签。
em, err := opts.EncMode() // 无CBOR标签 em, err := opts.EncModeWithTags(ts) // 不可变的CBOR标签 em, err := opts.EncModeWithSharedTags(ts) // 可变的共享CBOR标签
TagSet
和使用它的模式对于并发使用是安全的。DecMode
也有等效的API。
</details>// 使用"解码CWT"示例中定义的signedCWT结构体。 // 创建TagSet(并发安全)。 tags := cbor.NewTagSet() // 注册标签COSE_Sign1 18和signedCWT类型。 tags.Add( cbor.TagOptions{EncTag: cbor.EncTagRequired, DecTag: cbor.DecTagRequired}, reflect.TypeOf(signedCWT{}), 18) // 创建带有不可变标签的DecMode。 dm, _ := cbor.DecOptions{}.DecModeWithTags(tags) // 解组到带标签支持的signedCWT。 var v signedCWT if err := dm.Unmarshal(data, &v); err != nil { return err } // 创建带有不可变标签的EncMode。 em, _ := cbor.EncOptions{}.EncModeWithTags(tags) // 使用标签号组织signedCWT。 if data, err := cbor.Marshal(v); err != nil { return err }
与encoding/json
具有相同API的常用函数:
Marshal
, Unmarshal
NewEncoder
, (*Encoder).Encode
NewDecoder
, (*Decoder).Decode
注意:如果有剩余字节,Unmarshal
将返回ExtraneousDataError
,因为RFC 8949将有剩余字节的CBOR数据项视为格式错误。
UnmarshalFirst
解码第一个CBOR数据项并返回任何剩余字节。其他有用的函数:
Diagnose
, DiagnoseFirst
从CBOR数据生成人类可读的扩展诊断表示法。UnmarshalFirst
解码第一个CBOR数据项并返回任何剩余字节。Wellformed
如果CBOR数据项格式良好则返回true。与Go encoding
包相同或类似的接口包括:
Marshaler
, Unmarshaler
, BinaryMarshaler
, 和 BinaryUnmarshaler
。
RawMessage
类型可用于延迟CBOR解码或预先计算CBOR编码。
🔒 解码非常大或不定大小的数据时,使用Go的io.LimitReader
来限制大小。
对于处理非常大的数据(例如区块链)的系统,可能需要增加默认限制。
可以使用DecOptions
修改MaxArrayElements
、MaxMapPairs
和MaxNestedLevels
的默认限制。
v2.7.0 (2024年6月23日)增加了一些功能和改进,有助于大型项目(如Kubernetes)将CBOR用作JSON和Protocol Buffers的替代方案。其他改进包括速度提升、改进的内存使用、错误修复、新的序列化选项等。它通过了模糊测试(超过50亿次执行)并且具有生产质量。
有关更多详细信息,请参阅发行说明。
v2.6.0 (2024年2月)增加了重要的新功能、优化和错误修复。它对需要在CBOR和JSON之间转换数据的系统特别有用。新的选项和优化改进了对大整数、整数、映射和字符串的处理。
v2.5.0于2023年8月13日(星期日)发布,具有新功能和重要的错误修复。经过长期的beta测试 v2.5.0-beta (2022年12月) -> v2.5.0 (2023年8月),它已经经过模糊测试并具有生产质量。
重要: 👉 从v2.4或更早版本升级之前,请阅读发行说明中强调的显著变化。v2.5.0是一个大版本,对Unmarshal
中额外数据的错误处理等进行了错误修复,在升级之前应该进行审查。
有关新功能、改进和错误修复的列表,请参阅v2.5.0发行说明。
有关版本编号等更多信息,请参阅"版本和API更改"部分。
<!-- <details><summary>👉 基准测试比较: v2.4.0 vs v2.5.0</summary><p/> 待更新为v2.4.0 vs 2.5.0(不是beta2)。 @448提供的v2.4.0与v2.5.0-beta2的比较(已编辑以适应宽度)。 PR [#382](https://github.com/fxamacker/cbor/pull/382)将缓冲区返回到`Encode()`中的池。这会给`Encode()`增加一些开销,但`NewEncoder().Encode()`速度要快得多,并且使用的内存更少,如下所示: `fxamacker/cbor` 是一个完全符合 [IETF STD 94 (RFC 8949)](https://www.rfc-editor.org/info/std94) 标准的 CBOR 编解码器。它还支持 CBOR 序列 ([RFC 8742](https://www.rfc-editor.org/rfc/rfc8742.html)) 和扩展诊断表示法 ([RFC 8610 附录 G](https://www.rfc-editor.org/rfc/rfc8610.html#appendix-G))。 CBOR 的主要特性包括: | CBOR 特性 | 描述 | | :--- | :--- | | CBOR 标签 | API 支持内置和用户自定义标签。 | | 首选序列化 | 整数编码为最少字节。可选浮点数 64 → 32 → 16 位。 | | 映射键排序 | 无序、长度优先(规范 CBOR)和字节字典序(CTAP2)。 | | 重复映射键 | 编码时始终禁止,解码时可选允许/禁止。 | | 不定长度数据 | 编码和解码时可选允许/禁止。 | | 格式正确性 | 始终检查和强制执行。 | | 基本有效性检查 | 可选检查 UTF-8 有效性和重复映射键。 | | 安全考虑 | 防止整数溢出和资源耗尽(RFC 8949 第 10 节)。 | 已知限制在[限制部分](#limitations)中注明。 Go 中切片、映射、指针等的 nil 值编码为 CBOR null。空切片、空映射等编码为空 CBOR 数组和映射。 解码器检查所有必需的格式正确性错误,包括所有"子类型"的语法错误和数据不足。 在验证格式正确性后,基本有效性错误的处理如下: * 无效的 UTF-8 字符串:解码器可选检查并返回无效 UTF-8 字符串错误。此检查默认启用。 * 映射中的重复键:解码器可选忽略或强制拒绝重复映射键。 在解码格式正确的 CBOR 数组和映射时,解码器保存遇到的第一个错误并继续处理下一个项目。未来可能会添加不同处理方式的选项。 默认情况下,解码器将浮点数 NaN 和无穷大的时间值视为 CBOR Null 或 CBOR Undefined。 __点击展开主题:__ <details> <summary>重复映射键</summary><p> 该库提供了快速检测和拒绝重复映射键的选项,基于将 Go 特定数据模型应用于 CBOR 的扩展通用数据模型,以确定重复或不同的映射键。检测依赖于 CBOR 映射键在解码并应用到用户提供的 Go 映射或结构时是否为重复"键"。 `DupMapKeyQuiet` 关闭重复映射键的检测。它尝试使用"保留最快"方法,根据 Go 数据类型选择"保留第一个"或"保留最后一个"。 `DupMapKeyEnforcedAPF` 强制检测和拒绝重复映射键。当检测到第一个重复键时,解码立即停止并返回 `DupMapKeyError`。错误包括重复的映射键和索引号。 APF 后缀表示"允许部分填充",因此目标映射或结构在出错时可能包含一些已解码的值。调用者有责任响应 `DupMapKeyError`,如果协议要求,则丢弃部分填充的结果。 </details> <details> <summary>标签有效性</summary><p> 该库检查内置标签的有效性(当前为标签号 0、1、2、3 和 55799): * 标签内容的不允许类型 * 标签内容的不允许值 未知标签数据项(非标签号 0、1、2、3 或 55799)的处理方式有两种: * 解码到空接口时,未知标签数据项将解码为 `cbor.Tag` 数据类型,其中包含标签号和标签内容。标签内容将解码为 CBOR 数据类型的默认 Go 数据类型。 * 解码到其他 Go 类型时,未知标签数据项解码为指定的 Go 类型。如果 Go 类型注册了标签号,可以选择验证标签号。 解码器还有一个选项可以禁止标签数据项(将任何标签数据项视为错误),这由 CTAP2 规范 CBOR 等协议指定。 更多信息请参见[解码选项](#decoding-options-1)和[标签选项](#tag-options)。 </details> ## 限制 如果以下任何限制阻止您使用此库,请提出问题并附上您项目的链接。 * CBOR `Undefined`(0xf7)值解码为 Go 的 `nil` 值。CBOR `Null`(0xf6)更接近 Go 的 `nil`。 * 不支持 Go 映射键的 CBOR 映射键数据类型将被忽略,并在继续解码剩余项目后返回错误。 * 将注册的 CBOR 标签数据解码为接口类型时,解码器会创建一个指向与 CBOR 标签号匹配的注册 Go 类型的指针。这是 Go 的限制,需要使用指针。 ## 模糊测试和代码覆盖率 __代码覆盖率__ 在发布版本时始终为 95% 或更高(使用 `go test -cover`)。 __覆盖率引导的模糊测试__ 在发布版本前必须通过数十亿次执行。模糊测试使用非公开代码进行,最终可能会合并到此项目中。在此之前,OpenSSF Scorecard 等报告无法检测到此项目使用的模糊测试。 <hr> ## 版本和 API 变更 本项目使用[语义化版本控制](https://semver.org),因此 API 始终向后兼容,除非主版本号发生变化。 以下函数的签名与 encoding/json 相同,即使在主要新版本发布后,它们的 API 也将继续与 `encoding/json` 保持一致: `Marshal`、`Unmarshal`、`NewEncoder`、`NewDecoder`、`(*Encoder).Encode` 和 `(*Decoder).Decode`。 语义化版本控制的例外情况: - 新添加的 API 被标记为"可能变更"。 - master 分支中新添加的 API 从未在非测试版本中发布。 - 如果函数参数未更改,修复 bug 可能会改变行为(例如,之前版本遗漏的边缘情况现在会返回错误)。我们会尽量在发布说明中强调这些变更,并增加延长的测试期。例如,[v2.5.0-beta](https://github.com/fxamacker/cbor/releases/tag/v2.5.0-beta)(2022 年 12 月)→ [v2.5.0](https://github.com/fxamacker/cbor/releases/tag/v2.5.0)(2023 年 8 月)。 本项目避免对编码和解码函数的行为进行破坏性更改,除非需要改进对支持的 RFC 的遵从性(例如 RFC 8949、RFC 8742 等)。不改进标准遵从性的可见更改通常作为新的可选设置或新函数提供。 ## 行为准则 本项目采用了[贡献者契约行为准则](CODE_OF_CONDUCT.md)。如有任何问题或意见,请联系 [faye.github@gmail.com](mailto:faye.github@gmail.com)。 ## 贡献 在开始 PR 工作之前,请先提出问题。该改进可能已经被考虑过等。 更多信息,请参阅[如何贡献](CONTRIBUTING.md)。 ## 安全策略 安全修复将提供给 fxamacker/cbor 的最新发布版本。 完整的安全策略,请参阅 [SECURITY.md](SECURITY.md)。 ## 致谢 非常感谢本项目的所有贡献者! 我特别感谢 Bastian Müller 和 Dieter Shirley 在 CBOR 流模式等方面的建议和合作。 我非常感谢 Stefan Tatschner、Yawning Angel、Jernej Kos、x448、ZenGround0 和 Jakob Borg 在早期的贡献或支持。 非常感谢 Ben Luddy 在 v2.6.0 和 v2.7.0 中的贡献。 如果没有 Carsten Bormann 编写 CBOR RFC,这个库显然是不可能实现的。 特别感谢 Laurence Lundblade 和 Jeffrey Yasskin 在 IETF 邮件列表或 [7049bis](https://github.com/cbor-wg/CBORbis) 上的帮助。 非常感谢 Go 语言作者们创造了一个有趣且实用的编程语言,并提供了丰富的标准库! 本库使用了 `x448/float16`,该库曾经包含在内。作为独立包,`x448/float16` 对其他项目也很有用。 ## 许可证 版权所有 © 2019-2024 [Faye Amacker](https://github.com/fxamacker)。 fxamacker/cbor 基于 MIT 许可证授权。完整的许可证文本请参阅 [LICENSE](LICENSE)。AI辅助编程,代码自动修复
Trae是一种自适应的集成开发环境(IDE),通过自动化和多元协作改变开发流程。利用Trae,团队能够更快速、精确地编写和部署代码,从而提高编程效率和项目交付速度。Trae具备上下文感知和代码自动完成功能,是提升开发效率的理想工具。
AI小说写作助手,一站式润色、改写、扩写
蛙蛙写作—国内先进的AI写作平台,涵盖小说、学术、社交媒体等多场景。提供续写、改写、润色等功能,助力创作者高效优化写作流程。界面简洁,功能全面,适合各类写作者提升内容品质和工作效率。
全能AI智能助手,随时解答生活与工作的多样问题
问小白,由元石科技研发的AI智能助手,快速准确地解答各种生活和工作问题,包括但不限于搜索、规划和社交互动,帮助用户在日常生活中提高效率,轻松管理个人事务。
实时语音翻译/同声传译工具
Transly是一个多场景的AI大语言模型驱动的同声传译、专业翻译助手,它拥有超精准的音频识别翻译能力,几乎零延迟的使用体验和支持多国语言可以让你带它走遍全球,无论你是留学生、商务人士、韩剧美剧爱好者,还是出国游玩、多国会 议、跨国追星等等,都可以满足你所有需要同传的场景需求,线上线下通用,扫除语言障碍,让全世界的语言交流不再有国界。
一键生成PPT和Word,让学习生活更轻松
讯飞智文是一个利用 AI 技术的项目,能够帮助用户生成 PPT 以及各类文档。无论是商业领域的市场分析报告、年度目标制定,还是学生群体的职业生涯规划、实习避坑指南,亦或是活动策划、旅游攻略等内容,它都能提供支持,帮助用户精准表达,轻松呈现各种信息。
深度推理能力全新升级,全面对标OpenAI o1
科大讯飞的星火大模型,支持语言理解、知识问答和文本创作等多功能,适用于多种文件和业务场景,提升办公和日常生活的效率。讯飞星火是一个提供丰富智能服务的平台,涵盖科技资讯 、图像创作、写作辅助、编程解答、科研文献解读等功能,能为不同需求的用户提供便捷高效的帮助,助力用户轻松获取信息、解决问题,满足多样化使用场景。
一种基于大语言模型的高效单流解耦语音令牌文本到语音合成模型
Spark-TTS 是一个基于 PyTorch 的开源文本到语音合成项目,由多个知名机构联合参与。该项目提供了高效的 LLM(大语言模型)驱动的语音合成方案,支持语音克隆和语音创建功能,可通过命令行界面(CLI)和 Web UI 两种方式使用。用户可以根据需求调整语音的性别、音高、速度等参数,生成高质量的语音。该项目适用于多种场景,如有声读物制作、智能语音助手开发等。
AI助力,做PPT更简单!
咔片是一款轻量化在线演示设计工具,借助 AI 技术,实现从内容生成到智能设计的一站 式 PPT 制作服务。支持多种文档格式导入生成 PPT,提供海量模板、智能美化、素材替换等功能,适用于销售、教师、学生等各类人群,能高效制作出高品质 PPT,满足不同场景演示需求。
选题、配图、成文,一站式创作,让内容运营更高效
讯飞绘文,一个AI集成平台,支持写作、选题、配图、排版和发布。高效生成适用于各类媒体的定制内容,加速品牌传播,提升内容营销效果。
专业的AI公文写作平台,公文写作神器
AI 材料星,专业的 AI 公文写作辅助平台,为体制内工作人员提供高效的公文写作解决方案。拥有海量公文文库、9 大核心 AI 功能,支持 30 + 文稿类型生成,助力快速完成领导讲话、工作总结、述职报告等材料,提升办公效率,是体制打工人的得力写作神器。
最新AI工具、AI资讯
独家AI资源、AI项目落地
微信扫一扫关注公众号