hi,欢迎访问本站!
当前位置: 首页系统/服务器正文

IPFS-文件HASH值计算

墨初 系统/服务器 1阅读

文章目录 IPFS如何计算文件hash?IPFS-Multihash易用需求:Base58

IPFS如何计算文件hash?

IPFS采用了SHA2-256这个安全级别还算高的算法,对任意长度的内容,生成的HASH值长度固定,都是32个字节。

在Linux下,直接用sha256sum可以计算SHA2-256格式的HASH值:

[root@VM_0_14_centos bin]# sha256sum ipfsfile.txt e150a1ec81e8e93e1eae2c3a77e66ec6dbd6a3b460f89c1d08aecf422ee401a0 ipfsfile.txt[root@VM_0_14_centos bin]# ./ipfs add ipfsfile.txtadded QmQU2gS4gZ7TpiTECjDUxdQFd9bBBEWxDxPPfhLfYHVuei ipfsfile.txt 7 B / ? [---------------------------------------------------------------------------------=------] [root@VM_0_14_centos bin]#

得到的结果有64字节,其原因是因为用了十六进制的表示方式,每个字符表示4个bit,加在一起就是256bit,也就是32字节。

但在IPFS中,并不能利用上面得到的SHA2-256结果,去确定文件地址,因为IPFS还有一些额外的因素需要考虑。 我们把 ipfsfile.txt 加入到IPFS中,除了正文里面的 123456 几个字符之外,IPFS还会添加一些元数据。 通过如下命令我们可以看到IPFSF里面到底存放了什么内容:

[root@VM_0_14_centos bin]# ./ipfs object get QmQU2gS4gZ7TpiTECjDUxdQFd9bBBEWxDxPPfhLfYHVuei{"Links":[],"Data":"\u0008\u0002\u0012\u0007123456\n\u0018\u0007"}[root@VM_0_14_centos bin]#

返回的是一个JSON格式的字符串,Data显示了具体的内容。可见在文件的原始内容之外,添加了一些其他的数据。** IPFS会把文件数据以unixfs这种格式保存,可以认为,它是IPFS的核心数据结构MerkleDAG的一个表现方式。 **

我们可以通过获取IPFS的原始格式的数据,来计算正确的HASH值。IPFS保存的内容会被分成许多块(block),本例的文件因为比较小,一个块就可以保存。 所以,我们可以用如下的命令直接获取IPFS block的内容:

[root@VM_0_14_centos bin]# ./ipfs block get QmQU2gS4gZ7TpiTECjDUxdQFd9bBBEWxDxPPfhLfYHVuei | sha256sum1f9b484934c481946f11af0d87f8c04603fa8bfa6b8589185edf506c1e1cb09b -[root@VM_0_14_centos bin]#

该block的HASH值用十六进制数表示为:1f9b484934c481946f11af0d87f8c04603fa8bfa6b8589185edf506c1e1cb09b 。它也就是IPFS用特定格式保存文件之后的HASH值。

是否用该HASH值就能得到我们通常看到的IPFS文件的HASH值?好像不是那么回事,因为我们看到的文件HASH值都是以Qm开头的,显然在这里对不上号。这就涉及到另外一个话题——动态选择HASH算法的设计。

IPFS-Multihash

【推荐】官方:https://github.com/multiformats/multihash

虽然现在SHA2-256还比较安全,但随着科技的发展,说不定哪天就突然有人宣布,可以破解它呢?那自然需要采用更先进的算法。但IPFS的协议制定好了,也不能随便改。怎么办呢?虽然现在用的是SHA2-256,但可以宣称我支持多种HASH算法,到时候升级算法即可,但不会有大的架构改动。

于是,IPFS采用了multihash这种简单的HASH表示方式,支持多种HASH算法。如果未来修改算法,用的仍然是multihash,保证了表达方式的持续性。

multihash是一种自识别hash (Self identifying hashes)

multihash 多重哈希 遵循TLV 模式(type-length-value)。它其实就是一个字符串,由三部分组成:HASH算法编码、HASH值的长度(字节数)、HASH 值。

SHA2-256的编码为0x12,其HASH摘要长度为32字节(十六进制数为0x20)。把1220加到前面所得HASH值的开头,我们得到本例文件的multihash编码(十六机制):

12201f9b484934c481946f11af0d87f8c04603fa8bfa6b8589185edf506c1e1cb09b

官方sha-256 格式demo: 总结:我们把 ipfsfile.txt 加入到IPFS中,除了正文里面的 xxx 几个字符之外,IPFS还会添加一些元数据。然后对这个添加元数据的文件进行了sha256sum,然后再multihash 规则(前面加1120),文件的multihash编码(十六机制)。

易用需求:Base58

【推荐】官网:https://github.com/keis/base58

但这个HASH值显然也不是我们看到的内容。那是怎么回事呢?它太长了,一堆数字读起来也不容易,所以需要再进行编码,压缩其长度,且容易被传播。为此,IPFS采用了Base58这种编码。

Base58最早被比特币采用,如今在区块链项目中非常流行,经常用于表示钱包地址。做过开发的朋友可能比较了解Base64这种编码,能把任意二进制内容转换成方便软件查看的可读字符。

但Base64有一些缺点,就是某些字符不和谐,比如,O和0容易混淆,+和/等符号,很容易让人把一个完整的字符串认为是两个不同的字符串,形成阅读上的障碍。有时候我们用鼠标一点,想自动选中整个字符串,却因为这些符号的干扰,导致选择操作没有那么高效。因此,就诞生了Base58这种编码。

设计Base58主要的目的是:

避免混淆。在某些字体下,数字0和字母大写O,以及字母大写I和字母小写l会非常相似。不使用"+“和”/"的原因是非字母或数字的字符串作为帐号较难被接受。没有标点符号,通常不会被从中间分行。大部分的软件支持双击选择整个字符串。

Base58的代码非常简单,查看官网https://github.com/keis/base58

python安装模块 base58 进行验证

pip install base58

[root@VM_0_14_centos ~]# pythonPython 2.7.5 (default, Aug 7 2019, 00:51:29) [GCC 4.8.5 20150623 (Red Hat 4.8.5-39)] on linux2Type "help", "copyright", "credits" or "license" for more information.>>> import base58>>> base58.b58encode_int(int("12201f9b484934c481946f11af0d87f8c04603fa8bfa6b8589185edf506c1e1cb09b", 16))'QmQU2gS4gZ7TpiTECjDUxdQFd9bBBEWxDxPPfhLfYHVuei'>>>

基于前面生成的multihash 编码(12201f9b484934c481946f11af0d87f8c04603fa8bfa6b8589185edf506c1)进行计算,得到的结果 QmQU2gS4gZ7TpiTECjDUxdQFd9bBBEWxDxPPfhLfYHVuei 正是前面我们用ipfs add命令得到的HASH值!

注意: IPFS现在的multihash值,都是以1220开头的,按照Base58的算法,算出来的结果就都是以Qm开头。

总结:我们把 ipfsfile.txt 加入到IPFS中,除了正文里面的 xxx 几个字符之外,IPFS还会添加一些元数据,形成IPFS文件。然后对这个添加元数据的文件进行了sha256sum,然后再multihash 规则(前面加1120),文件的multihash编码(十六机制)。因为这个不好记忆识别,它又用 base58对我们的 multihash 生成最终的IPFS文件的HASH值。

简化总结为:原始数据添加元数据封装成IPFS文件 -> 计算SHA2-256 -> 封装成multihash -> 转换成Base58

标签:
声明:无特别说明,转载请标明本文来源!