【了解】Filecoin应用的“哈希”应用技术
什么是哈希算法它的作用是什么
民间常言:“说唱有嘻哈,算法有哈希。”在了解比特币投资和区块链技术中,哈希算法作为“常客”时常出现。但大多数朋友对它知之甚少,为它晦涩难懂的内涵所头疼。那么今天我们就来简单说说,什么是“哈希算法”?
哈希音译自“Hash”,又名为“散列”。本质上是一种计算机程序,可接收任意长度的信息输入,然后通过哈希算法,创建小的数字“指纹”的方式。例如数字与字母的结合,输出的就为“哈希值”。从数学术语上说,就是这个哈希函数,是将任意长度的数据,映射在有限长度的域上。总体而言,哈希函数用于,将消息或数据压缩,生成数据摘要,最终使数据量变小,并拥有固定格式。
那么哈希算法的作用又是什么呢?
(1) 在庞大的数据库中,由于哈希值更为短小,被找到更为容易,因此,哈希使数据的存储与查询速度更快。
(2) 哈希能对信息进行加密处理,使得数据传播更为安全。
哈希算法解决了什么生活问题?
看似深奥的数学函数,又或是计算机程序的哈希算法,其实跟我们的生活息息相关。就拿每年双十一的快递来说,实际上,哈希算法原理提高了快递入库出库的速度。为什么呢?
双十一一过,大家剁手后,一定收快递收到手软,手机短信抖个不停。这个时间段,双十一快递员可能没时间挨家挨户送上门,而是选择往驿站一扔。当驿站将快递入库后,你的手机会收到这样一条信息——
【XX收快】您的XX快递已到(原菜鸟驿站)65号店取货吗A10-8-9856,请9点至21点取货,电话xxx-xxxxxxxx)
大家重点看看这个取货码:A10-8-9856。这可不是一堆乱码。这串数值,就是驿站员能快速找到你快递的关键。
A10指的是货架编码,8指的是第8层,9856指的是订单后四位。因此每个驿站小哥只需要瞄一眼,就能瞬间知道你的快递所在位了。
因此,哈希算法最核心的用处,就是高速存取。在区块链技术中,它才真正大展身手。以下是它在区块中的具体作用:
(1) 快速验证。只需要验证摘要,就能比较两个数据是否相等。
(2) 防止篡改。只需要传递数据的摘要即可传递该数据,并防止在传递过程中被篡改。
(3) 用于POW共识算法工作量证明。目前比特币和以太坊,都使用POW共识机制。
哈希算法有千千万万种,其中,“安全哈希算法”(SHA 256)是保护数字信息,最安全的方式之一。它是由美国国安局设计、美国国家标准与技术研究院发布的一套哈希算法。其摘要长度是256bits,因此被称为“SHA256”。它们都在网络数据和区块链技术应用中,有着重大作用,也是理解区块链的重要一环。
——————————————————
哈希在IPFS中起着非常重要作用,因为它们用于寻址分布式网络中的内容。当系统将密码散列作为基本构建块时,需要更新策略,以防万一使用的哈希算法在某些时候被认为很弱或者不安全。
那IPFS项目如何利用“多重哈希”来确保哈希可升级并可以在同一应用程序中共存呢?
哈希需要用到散列,散列实际上并不像听起来那么可怕,散列实际上只是一个函数,它接受一些任意输入并返回固定大小的字母数字字符串,该字母数字字符串的外观取决于给定的哈希算法。
举例一个简单的哈希函数,我们有一条消息为“ abc”,这是我们的输入。我们自定义哈希函数的算法采用输入消息的每个字符,并将其向前移动三个字母。这将导致哈希摘要“def”。
现在,我们看一些现实世界中的哈希函数,只是算法显然更复杂。例如,Git使用SHA-1,它会产生一个160位的哈希,通常以40位数的十六进制数表示。它哈希原始内容(二进制数据),树对象和提交。
如果你的计算机上安装了Git,可以自己尝试一下,运行以下命令:返回的摘要为
8baef1b4abc478178b004d62031cf7fe6db6f903
哈希算法将始终为给定的输入返回相同的哈希。这样,从发送方接收数据时,可以验证完整性。但是,不可能从哈希中得出输入。
事实证明,Git实际上并没有对原始输入进行哈希处理,而是blob在哈希处理之前在输入内容之前加上了输入内容的大小。如果你尝试使用OpenSSL的SHA-1实现来验证摘要,则会注意到它将返回与“ abc”不同的哈希值。
总结:
哈希算法将输入转换为摘要的结果
算法返回固定长度(例如SHA1返回160位哈希)
对于给定的输入,它们始终返回相同的哈希值
从哈希中得出输入是(或应该是)不可能的
哈希值是一个非常好的存在,我们可以使用哈希值来验证内容和数据的完整性,此外,哈希值也可以非常紧凑。但有时它们证明不够安全或不够坚固,攻击者会设法进行破坏。
想象一个简单但常见的场景,用户密码存储在某个数据库中,由于其他原因,不想以纯文本形式存储密码。假设我们将这些密码存储为MD5散列,第二天,MD5被认为是不安全的。此时我们必须将哈希算法升级到更安全的方式。
升级哈希算法在技术上确实是一个挑战,因为要随着时间的推移,升级处理一个大型的分布式系统。需要找到一种在保持现有系统完好无损的同时(尽可能快)升级到其他哈希算法的方法。
此时问题是,现有系统通常依赖于仅假设某种哈希类型及其长度的API。需要考虑有多少个Git存储库,每个对象都是一个160位十六进制哈希(40位)。当Git切换到SHA-2(256位哈希)时会发生什么情况,以及将破坏多少工具和应用程序。而引入版本控制系统可以避免类似的问题。
版本哈希是将某些版本作为哈希的一部分引入,以便系统可以轻松确定它正在处理的哈希。以之前使用Git计算的'abc'哈希为例:
如果这是一个密码哈希,我们必须验证它是否是正确的密码,我们只需将此计算的哈希与数据库中的哈希进行比较即可。但是,如前所述,我们希望在不中断系统的情况下迁移到其他哈希算法。例如,与SHA-256相同的输入看起来完全不同:
BA7816BF8F01CFEA414140DE5DAE2223B00361A396177A9CB410FF61F20015AD
为了预先知道我们实际上正在处理不同的哈希版本,可以引入这样的版本号:
1:BA7816BF8F01CFEA414140DE5DAE2223B00361A396177A9CB410FF61F20015AD
这对于已经使用非版本哈希的系统也非常有用。必须在版本更改之前创建没有冒号的任何哈希。任何带有冒号和版本号的哈希都可以以相应的方式进行处理(去除前两个字节(1:),并在这种情况下假定哈希为SHA-256哈希)。
一个明显的特征是版本类型可能与哈希类型的其余部分不兼容。例如s不是有效的十六进制数字。但是,大多数系统以十六进制(或base32,base64等)传递哈希。因此,在这些方案之上构建应用程序时会增加复杂性。如果必须存储数以百万计的哈希,那么长版本类型(如blake2字节类型)可能会产生很大的影响。
Multihash是一种协议(由IPFS使用),用于区分各种公认的哈希函数的输出。它的工作原理与我们刚刚完成的工作非常相似,只是它以一种智能的方式添加了一些额外的信息。
Multihash具有以下模式:
<hash-func-type><digest-length><digest-value>
其中<hash-func-type>描述了所使用的哈希函数-有一个哈希表可查看代码的映射方式。
该<digest-length>描述的长度<digest-value>以字节为单位。
<digest-value>是我们感兴趣的实际哈希值
以Multihash为例,对其转化后:
122041dd7b6443542e75701aa98a0c235951a28a0d851b11564d20022ab11d2589a8
注意:在十六进制代码中,两位数字等于一个字节。换句话说,前两位数字12可以转换为0001 0010。这就是为什么十六进制代码中的160位哈希是40位数字的原因。同样,通常在十六进制代码之前加注0x以表示它是十六进制代码。在这种情况下0x12,12是同一回事。