Bitcoin

哈希

我们作为非计算机专业的人去看一些技术资料的时候,经常会被一些讨厌的术语弄得很头疼。今天要聊的这个词叫”哈希“,理解什么是哈希是理解数据校验和加密技术的基础,所以这个概念是非常重要的,同时这个概念其实本身是很简单的。哈希( hash ) 这个词的英文本意是“切碎并搅拌”的意思,有一种菜就叫”Hash“ ,就是把很多食材切碎并搅拌在一起做成的,如下图:

实际中使用的一些哈希算法很多就跟这个做菜的过程类似,把给定的数据文件切成一块一块的,然后适当的排列出我们最终要得到的哈希值。当然本文中我们不去讨论这些具体的算法实现,只是来了解一下哈希运算的基本特征。

在计算机科学领域,所谓的哈希运算是指对任意一个数据文件,通过运算,得到一个简短的字符串与之对应。这个得到的字符串就叫做“哈希值”,或者简称”哈希“。具体一点,我们有原始数据 M,选择一个”哈希算法“ F(), 把 M 传递给 F() 就可以得到哈希值 X = F(M)。一个重要的特点是,对于给定的 F(),X 的长度是固定的。例如对于哈希算法 md5,算出的哈希值长度是 32 位,对于更为安全的 sha256 算法,那么输出就是 64 位(是指 64 位 8 进制数,也就是 256 位 2 进制数)。

一个可靠的哈希算法要满足三个条件:第一,给定一个数据文件 M 很容易算出它的哈希值 X = F(M);第二,根据 X 不能算出 M;第三,很难找出两个不同的数据,拥有相同的哈希值。所以,根据第一第二点,我们可以说哈希算法是一个单向的算法;同时,第三点也就意味着如果我们的数据在传输过程中有丝毫的损坏,那么当我们再次运算它的哈希值的时候,哈希值也会不同,所以人们经常会使用这个办法开检查自己下载的文件是否完好的下载了。

但是,没有一个实际的哈希算法是绝对安全的。我们可以这样来想,既然输出为固定的长度,证明输出的可能的哈希值的总数是有限的,而同时输入的数据文件又是任意的,无限的,所以不可避免的会出现不同的输入得到相同的输出,这样就撞车了。所以,理论上输出的哈希值越长,那么出现撞车的可能行就越小,那么相应的,这种哈希算法就可能更安全,但是同时计算速度会变慢。

实际中常用的三个哈希算法:第一个是 crc32,比较简单高效,安全性差,哈希值是 8 位,但是运算速度超快

84fb764c

另一种是 md5,输出为 32 位,运算慢一些,以前认为把它作为加密级别的哈希算法,最近几年人们发现其实它的撞车现象也是常见的,所以已经不推荐作为加密用的哈希了

d7f2b08853cc9d9c7664e4a421378c24

第三种,对一个数据进行 sha256 运算的输出是类似于这样的:

2cf24dba5fb0a30e26e83b2ac5b9e29e1b161e5c1fa7425e73043362938b9824

总之,比较简短高效的哈希算法可以用来做完整性校验(integrity verification),这样的哈希值也可以叫做”校验值“(checksum), 也可以用来做原始数据的代表,这时哈希值也可以叫做”指纹“(fingerprint)。比较长的哈希算法(例如 sha256)适合用在加密领域。