区块链 | IPFS:CID
🦊原文:Anatomy of a CID
🦊写在前面:本文属于搬运博客,自己留存学习。
1 CID
在分布式网络中与其他节点交换数据时,我们依赖于内容寻址(而不是中心化网络的位置寻址)来安全地定位和识别数据。
CID 规范起源于 IPFS,现在以 Multiformats 形式存在,并支持包括 IPFS、IPLD、libp2p 和 Filecoin 在内的系统。尽管我们在教程中会分享一些 IPFS 的例子,但本教程实际上是关于 CID 自身的结构,它作为这些分布式信息系统的核心标识符,用于引用内容。
内容标识符(CID)是一种自描述的内容寻址标识符。
自描述是指,标识符能够自行表达其含义或者数据类型。例如 HTTP 中的 URL就是一个自描述的标识符,因为它包含了指向资源的信息(如文件路径),并且基于协议和结构,用户和系统可以理解其含义。
CID 不指示内容存储的位置,而是基于内容本身形成一种地址。CID 的长度取决于内容的哈希,而不是内容本身的大小。由于在 IPFS 中大多数内容都使用 sha2-256 进行哈希处理,因此大多数 CID 都具有相同的大小,即 256 位或称 32 字节。
例如,如果我们在 IPFS 网络中存储 土豚 的图像,它的 CID 将如下所示:
QmcRD4wkPPi6dig81r5sLj9Zm1gDCL4zgpEj9CfuRrGbzF
访问方式:https://ipfs.io/ipfs/QmcRD4wkPPi6dig81r5sLj9Zm1gDCL4zgpEj9CfuRrGbzF
创建 CID 的第一步是使用 加密算法 转换输入的数据。具体来说,是将任意大小的输入映射到固定大小的输出。如下图所示:

这种转换称为 加密哈希摘要(cryptographic hash digest)或简称为 哈希。
个人理解:不管是文本、图片还是视频,它们在计算机中都是以二进制的形式进行存储的,即一个 01 字符串。而哈希函数要做的事,就是将不同文件不同长度的 01 字符串转换为固定长度的 01 字符串。
使用的 加密算法 必须生成具有以下特征的哈希:
- 确定性:对于任何给定的输入数据,加密算法必须始终产生相同的输出哈希,确保一致性。
- 抗碰撞性:即使输入数据发生微小变化,也应导致完全不同的哈希值,以保证数据的唯一性。
- 不可逆性:从哈希值应当无法反推出原始数据,确保数据的隐私和安全。
- 唯一标识:每份文件都应该有一个独特的哈希值,确保数据的不可篡改性和可追溯性。
当我们使用内容地址去获取数据时,我们可以保证看到数据的预期版本。这与中心化网络上的位置寻址有很大的不同,在中心化网络中,给定地址(URL)处的内容可能会随时间变化。
说明:在去中心化网络中,我们使用 CID 去获取数据;在中心化网络中,我们使用 URL 去获取数据。
哈希并不是 IPFS 所独有的,还有许多其他的哈希算法,如 sha2-256、blake2b、sha3-256 和 sha3-512,以及不再安全的 sha1 和 md5 等。IPFS 默认使用 sha2-256,尽管 CID 支持几乎任何强大的加密哈希算法。
2 CIDv0
随着时间的推移,某些哈希算法可能被证明对于 IPFS 和其他分布式信息系统的内容寻址是不够安全的。
因此,我们的系统需要支持多种加密算法,同时我们应该能够知道是哪种算法被用来生成特定内容的哈希值。为了支持多种哈希算法,我们使用了多重哈希。
2.1 多重哈希
多重哈希(multihash)是一种自描述的哈希,它本身包含元数据,这些元数据描述了其长度以及生成它的加密算法。
多重哈希遵循 TLV 模式,即 type — length — value。也就是说,原始哈希 value 前面附带着所使用的哈希算法的类型 type 和哈希的长度 length。如下图所示:

type:用于生成哈希的加密算法的标识符。例如,sha2-256 的标识符是 18,即十六进制的 12;length:哈希的实际长度。使用 sha2-256 时,它将是 256 位,相当于 32 字节;value:实际的哈希值;
通过查看 multicodec 表,可以获取各个哈希算法对应的标识符。
2.2 基数编码
为了将 CID 表示为紧凑的字符串而不是纯二进制(一串 0 和 1),我们可以使用基数编码(base encoding)。
在 IPFS 最初创建时,它使用 base58btc 编码来生成看起来像这样的 CID:
QmY7Yh4UquoXHLPFo2XbhXkhBvFoPwmQUSa92pxnxjQuPU
多重哈希和 base58btc 编码构成了第一版 CID,即如今所说的版本 CIDv0,以 Qm 开头的序列仍然是它的一个显著特征。
然而,随着时间的推移,人们开始对多重哈希是否足够的问题产生了疑问:
- 我们如何知道使用了什么方法来编码数据?
- 我们如何知道使用了什么方法来创建 CID 的字符串表示?我们是否会一直使用
base58btc?
为了应对这些担忧,有必要对 CID 的下一版本进行改进。
个人理解:在本文中,“基数编码” 是指将二进制转换为可读的字符串,“编码” 是指将文件转换为二进制。
3 CIDv1
CIDv0 使用多重哈希来支持多种哈希函数。这允许我们针对特定内容创建哈希值,且可以选择不同的哈希算法进行处理。有了这一机制,我们日后便能通过这些哈希值来辨识内容。
3.1 多码前缀
但当我们试图阅读数据本身时,如何知道采用了哪种编码方式?数据可能是由 CBOR、Protobuf 或纯 JSON 等编码的。为了解决这个问题,CIDv1 引入了另一个前缀,用以唯一标识所使用的编码方法。
个人理解:哈希是将任意长度的 01 字符串转换为固定长度的 01 字符串,而编码是将非 01 字符串的数据本身转换为 01 字符串。
多码前缀(multicodec prefix)指示了数据使用了哪种编码方式。如下图所示:

多码支持许多不同类型的编码,每种编码都有自己的简短码缀,可以在 complete 表中查看。
在上述示例中,我们了解到使用 dag-pb 编码的数据是如何被表示在 CID 中的。其中,dag-pb 是众多 IPLD 编码格式中的一种。由于 IPFS 总是选择一种 IPLD 格式来处理其数据,因此 IPFS 生成的 CID 中的多码前缀必然对应于一个 IPLD 编码。
IPLD 是指 Inter Planetary Linked Data,星际链接数据
需要指出的是,多码不仅仅是为了 IPFS 和 IPLD 而设计的,它还是 Multiformats 项目的一部分。这个项目最初是从 IPFS 分离出来的,现在它支持包括我们正在学习的 CID 规范在内的许多其他项目和协议。
3.2 版本前缀
添加多码前缀后,CIDv1 包含以下字段:
<multicodec><multihash-algorithm><multihash-length><multihash-hash>
那么我们如何区分不同版本的 CID 呢?答:版本前缀。如下图所示:

现在我们的 CID 看起来像这样:
<cid-version><multicodec><multihash>
其中,<cid-version> 代表 CID 的版本是 0 还是 1 。
注意:
<multihash>包含了<multihash-algorithm><multihash-length><multihash-hash>。特别地,只有 CIDv1 具有<cid-version>,而 CIDv0 只有<multihash>。
3.3 多基前缀
CIDv1 以二进制的形式为我们提供了以下信息:
<cid-version><multicodec><multihash>
由于二进制 CID 对人类不太友好,因此我们可以将这些二进制 CID 表示为字符串形式,即把二进制数据表示为字符串。
采用的就是前文提到的基数编码技术。
示例:
bafybeigdyrzt5sfp7udm7hu76uh7y26nf3efuylqabf3oclgtqy55fbzdi
在二进制和字符串形式之间转换数据需要进行基数编码,因此在处理字符串格式的 CID 时,我们需要知道应用于二进制数据的基数编码的类型。
在 CIDv0 中,哈希总是使用 base58btc 进行编码。因此我们可以直接假设 CIDv0 哈希是由 base58btc 编码的。然而,由于环境限制(例如 DNS 名称),我们需要支持其他基数编码的能力。你猜对了,我们可以添加另一个前缀!
多基数前缀(multibase prefix),用于表示 CID 在进行格式转换时使用的基数编码,仅用于 CID 的字符串形式:
Binary:
<cid-version><multicodec><multihash>
String:
<base>base(<cid-version><multicodec><multihash>)
其中,base( ) 应该是指使用某种基数编码方法,对括号中的内容进行基数编码。
让我们来分析两个 CID 的字符串形式示例:
CIDv0:
QmbWqxBEKC3P8tqsKc98xmWNzrzDtRLMiMPL8wBuTGsMnR
CIDv1:
bafybeigdyrzt5sfp7udm7hu76uh7y26nf3efuylqabf3oclgtqy55fbzdi
易知第一个 CID 是一个 CIDv0,因为它以 Qm 开头。所有以 Qm 开头的哈希,都可以解释为采用的是 base58btc 基数编码。第二个示例以 b 开头,这是 base32 的基数编码前缀标识符,大多数 IPFS 实现默认使用 base32。
4 One hash, multiple CID versions
我们可以将任何的 IPFS CID 粘贴到 CID Inspector 中,以可视化其所有前缀及其代表的内容。
4.1 示例 1:CIDv1
bafybeigdyrzt5sfp7udm7hu76uh7y26nf3efuylqabf3oclgtqy55fbzdi
通过 CID Inspector 工具查看结果:

我这里只截取了一部分,请自行查看剩余部分。
我们可以看到工具为我们解析了许多部分:
- 人类可读 CID:将 CID 的每个部分分解为人类可以轻松阅读的形式;
- 多基数:基数的标识符,在这个例子中是
b,代表base32; - 多编码:编码的标识符,在这个例子中是
0x70,代表dag-pb,一种 IPLD 格式; - 多哈希:将多哈希分解为所使用的哈希算法、哈希的长度、内容哈希本身。
其中,18 是哈希算法 sha2-256 的代码,哈希的长度是 256 位即 32 字节,内容哈希本身是十六进制的摘要。
从 “人类可读 CID” 中,我们可以看到在添加 CIDv1 的前缀之前,内容的原始哈希是:
C3C4733EC8AFFD06CF9E9FF50FFC6BCD2EC85A6170004BB709669C31DE94391A
4.2 示例 2:CIDv0
QmbWqxBEKC3P8tqsKc98xmWNzrzDtRLMiMPL8wBuTGsMnR
通过 CID Inspector 工具查看结果:

在 CIDv0 的结果中,多基数和多编码都显示为 “implicit”。这是由于 CIDv0 没有这两个前缀,因此它们被分别默认为 base58btc 和 dag-pb。
在原文的截图中,两个前缀都显示的是 “implicit”,但是我查看到的多编码并不是 “implicit”。
在 CIDV1(Base32) 标签下,我们看到:
bafybeigdyrzt5sfp7udm7hu76uh7y26nf3efuylqabf3oclgtqy55fbzdi
这与第一个示例中的 CID 完全相同!CID 检查器为我们提供了从 CIDv0 到 CIDv1 的转换。
注意,CIDv0 示例与 CIDv1 示例中的 “人类可读 CID” 的末尾完全相同:
C3C4733EC8AFFD06CF9E9FF50FFC6BCD2EC85A6170004BB709669C31DE94391A
这是因为这两个 CID 指向相同的内容,即本质上两个 CID 代表的是相同的哈希。
4.3 转换 CID 的版本
我们可以将任何的 CIDv0 转换为 CIDv1,但不能将任何的 CIDv1 转换为 CIDv0 。这是由于 CIDv1 支持多编码和多基数,而 CIDv0 不支持。事实上,只有具有以下属性的 CIDv1 可以转换为 CIDv0:
- 多基数 =
base58btc - 多编码 =
dag-pb - 多哈希算法 =
sha2-256 - 多哈希长度 = 32 字节
为了测试这个理论,你可以查看我们亲爱的 土豚 图片,它托管在 IPFS 网络上:
https://ipfs.io/ipfs/QmcRD4wkPPi6dig81r5sLj9Zm1gDCL4zgpEj9CfuRrGbzF
首先,从 URL 末尾复制 CID:
QmcRD4wkPPi6dig81r5sLj9Zm1gDCL4zgpEj9CfuRrGbzF
然后,将 CID 粘贴到 CID Inspector 工具中,并在页面底部找到等效的 CIDv1 值:
bafybeigrf2dwtpjkiovnigysyto3d55opf6qkdikx6d65onrqnfzwgdkfa
最后,将原始 URL 中的 CID 替换为转换后的 CID:
https://ipfs.io/ipfs/bafybeigrf2dwtpjkiovnigysyto3d55opf6qkdikx6d65onrqnfzwgdkfa
你应该看到的是相同的土豚图片。
相关文章:
区块链 | IPFS:CID
🦊原文:Anatomy of a CID 🦊写在前面:本文属于搬运博客,自己留存学习。 1 CID 在分布式网络中与其他节点交换数据时,我们依赖于内容寻址(而不是中心化网络的位置寻址)来安全地定位…...
PostgreSQL(十二)报错:Tried to send an out-of-range integer as a 2-byte value: 51000
目录 一、报错场景二、源码分析三、实际原因(更加复杂)四、解决思路 一、报错场景 今天写了一个历史数据处理程序,在开发环境、测试环境都可以正常执行,但是放到生产环境上就不行,报了一个这样的错误: or…...
Linux守护进程
进程组和会话在 UNIX 系统中是非常重要的概念,特别是在进行作业控制和终端会话管理时。下面是关于进程组和会话的详细解释: 进程组(Process Group) 定义与作用: 进程组是一个或多个进程的集合,这些进程通常…...
HarmonyOS 应用开发——入门
首先当然是华为的官方文档了,要认真学习: https://developer.huawei.com/consumer/cn/doc/harmonyos-guides-V2/start-overview-0000001478061421-V2 不想花时间看,可以看我下面总结的干货,哈哈 第一个问题:stage架构和fa架构的区…...
开源免费的发票识别OCR应用:Invoice
Invoice:轻松识别,发票电子化扫描烦恼消- 精选真开源,释放新价值。 概览 Invoice 是github社区上一个采用开源许可协议发布的增值税发票光学字符识别(OCR)解决方案项目。该项目不仅集成了预训练的高级模型,…...
关于Docker alpine
1.拉取alpine镜像 docker pull alpine 2.运行镜像成为容器 docker run -it --rm alpine sh (--rm标志确保容器在退出时被自动删除。) 3.容器建立后,运行 docker exec -it <container_id> sh 4.进入容器里的 alpine环境 ①.配置安装源 cat >/etc…...
【Elasticsearch运维系列】Elasticsearch7.12.1启动指定版本JDK:你学废了吗?
一、背景 一套生ES集群,版本为7.12.1,近期频繁告警,频繁出现索引分片异常,索引状态异常,导致应用无法正常写入ES,另外,也经常出现节点掉问题。通过分析相关ES日志,显示和当前JAVA G…...
思通数科大模型在智能数据查询系统中的深度应用:销售数据分析的革新
在企业决策支持系统中,销售数据分析占据着举足轻重的地位。思通数科的大模型技术,结合自然语言处理(NLP)和机器学习,为智能数据查询系统提供了强大的分析能力。本文将详细描述思通数科大模型在销售数据分析中的应用&am…...
上位机图像处理和嵌入式模块部署(树莓派4b和qt应用全屏占有)
【 声明:版权所有,欢迎转载,请勿用于商业用途。 联系信箱:feixiaoxing 163.com】 我们都知道,嵌入式应用一般都是为了某一个特定应用而存在的。也就是说,和pc不同,这个嵌入式板子一般都是为了解…...
QT:QT窗口(一)
文章目录 菜单栏创建菜单栏在菜单栏中添加菜单创建菜单项添加分割线 工具栏创建工具栏设置停靠位置创建工具栏的同时指定停靠位置使用QToolBar类提供的setAllowedAreas函数来设置停靠位置 设置浮动属性设置移动属性 状态栏状态栏的创建在状态栏中显示实时消息在状态栏中显示永久…...
matlab例题大全
1.第1章 MATLAB系统环境 1.1 注:plot函数为画图函数。例plot(x1,y1,:,x2,y2,*); 1.2 注:root为求根函数。p为方程变量前面系数矩阵。 1.3 注: 2*x3y-1*z 2; 8*x2*y3*z 4; 45*x3*y9*z 23 求:x,y,z的…...
SwiGLU激活函数
SwiGLU激活函数已经成为LLM的标配了。它是GLU的变体,公式如下: SwiGLU ( x , W , V , b , c , β ) Swish β ( x W b ) ⊗ ( x V c ) \operatorname{SwiGLU}(x, W, V, b, c, \beta)\operatorname{Swish}_\beta(x Wb) \otimes(x Vc) SwiGLU(x,…...
MySQL慢查询优化
当需要优化MySQL的慢查询时,通常需要结合多个方面进行分析和优化,包括索引优化、SQL语句重构、数据库结构调整等。下面,我将通过一个例子来说明如何优化MySQL的慢查询,包括多表关联和条件查询。 假设我们有一个简化的电子商务系统…...
开源数据可视化大屏对接表单数据实践!
如果你需要一个表单系统,进行数据收集;可以使用tduck填鸭进行私有化部署,进行表单制作,完成数据收集。 在实际业务中,往往需要将收集的数据进行展示或分析;此时就可以使用表单数据推送到TReport中…...
08.图形化界面字体问题处理
图形化界面字体问题处理 发现图形存在乱码,不显示文字 zabbix服务器的字符集所在的路径下: /usr/share/zabbix/assets/fonts 将本地windows系统的字体进行上传,选择一个自己喜欢的字体 上传到系统路径下并且直接覆盖掉 回到web浏览器界面…...
【代码随想录算法训练营第37期 第二天 | LeetCode977.有序数组的平方、209.长度最小的子数组、59.螺旋矩阵II】
代码随想录算法训练营第37期 第二天 | LeetCode977.有序数组的平方、209.长度最小的子数组、59.螺旋矩阵II 一、977.有序数组的平方 解题代码C: class Solution { public:vector<int> sortedSquares(vector<int>& nums) {int len nums.size();fo…...
Java:Servlet详解
目录 一、什么是Servlet 二、Servlet原理 Servlet的生命周期 三、 Servlet注释 WebServlet 一、什么是Servlet Servlet是JavaWeb开发的一种技术,Servlet程序需要部署在Servlet容器(服务端)中才能运行,常见的Servlet容器有Tom…...
Oracle存储过程怎么定义类并继承
在Oracle数据库中,存储过程(Stored Procedure)是用于执行特定功能的预编译的SQL代码块。然而,Oracle的存储过程并不直接支持面向对象的编程概念,如类(Class)和继承(Inheritance&…...
14_Scala面向对象编程_属性
文章目录 属性1.类中属性声明2.系统默认赋值3.BeanProperty4.整体代码如下 属性 1.类中属性声明 // 1.给Scala声明属性;var name :String "zhangsan"val age :Int 302.系统默认赋值 scala由于初始化变量必须赋值,为了解决此问题可以采…...
什么是网页反作弊
在搜索引擎技术中,网页反作弊是指一种防止网页排名被恶意操纵的技术。搜索引擎会根据特定的算法来评估网页的相关性和质量,以决定其在搜索结果中的排名。然而,有些人可能会尝试通过各种不正当的手段来提高自己网页的排名,这被称为…...
MPNet:旋转机械轻量化故障诊断模型详解python代码复现
目录 一、问题背景与挑战 二、MPNet核心架构 2.1 多分支特征融合模块(MBFM) 2.2 残差注意力金字塔模块(RAPM) 2.2.1 空间金字塔注意力(SPA) 2.2.2 金字塔残差块(PRBlock) 2.3 分类器设计 三、关键技术突破 3.1 多尺度特征融合 3.2 轻量化设计策略 3.3 抗噪声…...
可靠性+灵活性:电力载波技术在楼宇自控中的核心价值
可靠性灵活性:电力载波技术在楼宇自控中的核心价值 在智能楼宇的自动化控制中,电力载波技术(PLC)凭借其独特的优势,正成为构建高效、稳定、灵活系统的核心解决方案。它利用现有电力线路传输数据,无需额外布…...
视频字幕质量评估的大规模细粒度基准
大家读完觉得有帮助记得关注和点赞!!! 摘要 视频字幕在文本到视频生成任务中起着至关重要的作用,因为它们的质量直接影响所生成视频的语义连贯性和视觉保真度。尽管大型视觉-语言模型(VLMs)在字幕生成方面…...
Java 加密常用的各种算法及其选择
在数字化时代,数据安全至关重要,Java 作为广泛应用的编程语言,提供了丰富的加密算法来保障数据的保密性、完整性和真实性。了解这些常用加密算法及其适用场景,有助于开发者在不同的业务需求中做出正确的选择。 一、对称加密算法…...
三体问题详解
从物理学角度,三体问题之所以不稳定,是因为三个天体在万有引力作用下相互作用,形成一个非线性耦合系统。我们可以从牛顿经典力学出发,列出具体的运动方程,并说明为何这个系统本质上是混沌的,无法得到一般解…...
【C语言练习】080. 使用C语言实现简单的数据库操作
080. 使用C语言实现简单的数据库操作 080. 使用C语言实现简单的数据库操作使用原生APIODBC接口第三方库ORM框架文件模拟1. 安装SQLite2. 示例代码:使用SQLite创建数据库、表和插入数据3. 编译和运行4. 示例运行输出:5. 注意事项6. 总结080. 使用C语言实现简单的数据库操作 在…...
关于 WASM:1. WASM 基础原理
一、WASM 简介 1.1 WebAssembly 是什么? WebAssembly(WASM) 是一种能在现代浏览器中高效运行的二进制指令格式,它不是传统的编程语言,而是一种 低级字节码格式,可由高级语言(如 C、C、Rust&am…...
Android15默认授权浮窗权限
我们经常有那种需求,客户需要定制的apk集成在ROM中,并且默认授予其【显示在其他应用的上层】权限,也就是我们常说的浮窗权限,那么我们就可以通过以下方法在wms、ams等系统服务的systemReady()方法中调用即可实现预置应用默认授权浮…...
VM虚拟机网络配置(ubuntu24桥接模式):配置静态IP
编辑-虚拟网络编辑器-更改设置 选择桥接模式,然后找到相应的网卡(可以查看自己本机的网络连接) windows连接的网络点击查看属性 编辑虚拟机设置更改网络配置,选择刚才配置的桥接模式 静态ip设置: 我用的ubuntu24桌…...
七、数据库的完整性
七、数据库的完整性 主要内容 7.1 数据库的完整性概述 7.2 实体完整性 7.3 参照完整性 7.4 用户定义的完整性 7.5 触发器 7.6 SQL Server中数据库完整性的实现 7.7 小结 7.1 数据库的完整性概述 数据库完整性的含义 正确性 指数据的合法性 有效性 指数据是否属于所定…...
