补充哈希函数

时间:2014-10-07 12:25:00

标签: algorithm hash

是否存在满足以下等式的哈希类型:

  

哈希(哈希(X)+ Y)=哈希(X + Y)

上下文:
我正在使用一个只能附加的数据库,该数据库必须在领域内同步 为了保证同步按预期发生,我们对两个数据库进行哈希并进行比较 由于数据库有点庞大,我们使用的哈希函数需要花费大量的时间来计算。所以我想知道:如果我已经拥有给定数据X的哈希值和新数据Y,如果我只能哈希Y和"合并"哈希我可以节省很多时间......

4 个答案:

答案 0 :(得分:2)

给定模数M,我们可以采用Hash(X) = X mod M。然后

Hash(Hash(X) + Y) = ((X mod M) + Y) mod M = (X + Y) mod M = Hash(X + Y).

这不是一个很好的哈希函数,但是,与Hash到目前为止的其他提案不同,它并非完全没用。

它本质上也是唯一的提案,因为通过替换Y = Z - Hash(X),我们得到了

Hash(Z) = Hash(Z + (X - Hash(X))),

所以Hash在将X - Hash(X)的整数倍添加到其参数时是不变的,因此在G X - Hash(X)的{​​{1}}的最大公约数的倍数下加上X G 1}}。此外,由于X - Hash(X)除以Hash,因此0..G-1在域{{1}}上是一对一的。

答案 1 :(得分:1)

如果" +"是连接,然后MD5,SHA1,SHA256(和更多)将几乎满足这个等式。这些散列函数的输出是它们的内部状态,因此您可以计算Hash(X + Y),仅知道Hash(X)和Y.此散列函数的此属性在Length Extension Attack中使用(在设计错误的加密中)。请注意,加密哈希函数的设计没有考虑到这个漏洞(SHA3除外)。

答案 2 :(得分:1)

http://en.wikipedia.org/wiki/Merkle_tree已用于此类问题(请参阅该网址的下半部分)。将您的数据视为树的叶子,然后从下到上计算树顶部的散列函数,其中在节点处计算的散列函数是散列(A || B),其中A和B是在其子节点计算的哈希函数。

另一种选择是仅间隔生成整个数据库的哈希值,并分配自上次完整哈希以来添加到其中的连接数据的哈希值。这几乎只是计算和分发merkle树哈希以及树的右边界的一些较新值的退化版本。

答案 3 :(得分:0)

解决(编辑过的)帖子中的实际问题的一种方法,以及类似于文字问题的方法,是以一些方便大小的块来散列数据,其中方便性基于数据库的大小以及更新的预期大小。实际上,数据的哈希值是块的哈希值的串联,并遵循相等:

 HASH(x:Y) = HASH(X):HASH(Y)

其中:是连接运算符。

如果使用块散列存储块大小,则块不必具有相同的大小。当然,在这种情况下,散列函数不再是确定性的,为了进行比较,您需要块大小序列以便计算更新的散列。

对于确定性散列,您可以在末尾使用固定的块大小和单个(较短)块。通过将最后一个块的大小预先添加到哈希序列来组装完整哈希。为了计算更新的散列,有必要在截断块的开头开始散列,这需要稍微重复一点,但相对来说它不会很多。

对于以兆兆字节为单位的数据库,合理的块大小可能是1GB;如果散列是128位,则散列的总大小将是每TB数据库16kb,这相对来说是微不足道的。如果太字节超过你对#34;有点大的预期,那么适当调整块大小:)

该技术的另一个优点是可以并行计算块散列。如果数据库更新缓存在RAM中,则并行哈希可能是一个很大的胜利。