通过哈希算法检验大量数据(比如大量文件)的一致性时,常见的存储方案:
哈希列表(Hash List)
- 原理:
- 计算每个数据的哈希值,保存为一个列表。
- 记录该列表的哈希值,用于检验整体的一致性。
- 当发现整个 Hash List 的哈希值变化时,需要遍历检验每个数据的哈希值是否变化,从而找出变化的数据。时间复杂度为 O(n) 。
哈希链(Hash Chain)
-
原理:
-
计算每个数据的哈希值。
-
将两个数据的哈希值组合,计算哈希值,再与下一个数据的哈希值组合,计算哈希值。以此类推,最后得到链尾的哈希值。
-
-
如果任一节点的哈希值发生变化,则在哈希链中,其后所有节点的哈希值都会变化。
哈希树(Hash Tree)
:又称为默克尔树(Merkle Tree)
-
原理:
-
计算每个数据的哈希值,保存为二叉树的叶子节点。
-
将二叉树中的节点两两组合计算哈希值,作为父节点的哈希值。以此类推,最后得到根节点的哈希值。
-
-
从一个叶子节点到根节点的路径称为 Merkle 路径。
-
当发现根节点的哈希值变化时,需要按二分法检验子孙节点的哈希值是否变化,从而找出变化的数据。时间复杂度为 O(logn) ,效率较高。
-
假设哈希值存储在其它主机上,则采用 Hash List、Hash Chain 时,本机需要下载所有数据的哈希值用于遍历检验。采用 Merkle Tree 时,本机只需下载 Merkle 路径的相关节点的哈希值用于检验,开销更低。