高效的绳索重新散列

时间:2017-02-08 09:58:19

标签: algorithm data-structures hash rope

给定rope,假设我们需要知道它的哈希值(通过一些哈希函数传递所有叶子的串联)。

现在,当一根绳子叶子发生变化时,再次重新计算整根绳子的有效方法是什么?即像O(log n)而不是O(n)。

一种方法是使用Merkle tree。但是,这会导致诸如......

之类的问题
  • 空的非叶节点或具有零长度子串的叶节点会影响散列,即使它们对有效绳索内容没有影响;
  • 将子树右侧的节点移动到该子树的右侧兄弟的左侧会影响最终的哈希值,但不会影响有效的绳索内容。

有更好的算法吗?哈希函数不需要加密安全,只是足以避免可能的冲突。

1 个答案:

答案 0 :(得分:3)

正如绳索的任何节点存储左子树的大小(或者如果它是叶子一样),任何节点都可以另外存储对应于左子树的字符串的多项式哈希(或者如果它是叶)。

当重新计算节点的权重时,也会为该节点重新计算哈希值,并具有相同的渐近复杂度。

例如,让节点及其中的值为:

    left     right    string     weight
1:                     abcd         4
2:    1        4                    4
3:                     ef           2
4:    3        5                    2
5:                     ghi          3

多项式散列是一些固定常数p和q:

h(s [0] s [1] ... s [n-1])=(s [0] * p ^(n-1)+ s [1] * p ^(n-2) + ... + s [n-1] * p ^ 0)mod q。

因此,我们存储了以下哈希值,所有模数为q:

         hash
1:  a*p^3 + b*p^2 + c*p^1 + d*p^0
2:  a*p^3 + b*p^2 + c*p^1 + d*p^0
3:  e*p^1 + f*p^0
4:  e*p^1 + f*p^0
5:  g*p^2 + h*p^1 + i*p^0

关于计算模q的说明。 在这里和下面,所有的加法和乘法都是以模q进行的。 换句话说,我们以ring of integers模q运算。 我们使用的事实是

(a?b)mod q =((a mod q)?(b mod q))mod q

为?操作是加法,减法和乘法。 因此,每次我们执行其中一个操作时,我们会立即附加mod q以保持数字较小。 例如,如果p和q小于2 30 = 1,073,741,824,则可以在32位整数类型中进行加法和减法,并且对于中间64位整数类型,乘法将是正确的。 在每次乘法之后,我们立即采用模q的结果,使其再次适合32位整数。

现在,我们如何获取根的哈希值 - 例如,使其成为某个节点的左子节点,或者仅获取整个字符串的哈希值?

我们从根到右,我们必须添加权重和合并哈希。结果我们可以做(记住一切都是模数q):

({a * p ^ 3 + b * p ^ 2 + c * p ^ 1 + d * p ^ 0} * p ^ 2 + {e * p ^ 1 + f * p ^ 0})* p ^ 3 + {g * p ^ 2 + h * p ^ 1 + {{ 1}} * p ^ 0}

大括号中的值是存储在out节点中的值。 我们向右前进。 起床时,我们记住到目前为止收集的重量,将左侧散列乘以p乘以该重量的幂(其中p ^ 3和p ^(3 + 2 = 5)来自),并添加累积的右侧哈希。

结果值只等于整个字符串的哈希值:

i * p ^ 8 + a * p ^ 7 + b * p ^ 6 + c * p ^ 5 + d * p ^ 4 + e * p ^ 3 + f * p ^ 2 + g * p ^ 1 + h * p ^ 0

这里有几点说明。

  1. 我们必须预先计算,或许是懒惰,p modulo q的幂能够快速乘以它们。

  2. 如果我们在节点中存储整个子树的哈希值,而不仅仅是左子树的哈希值,整个结构可能会变得更加清晰。但是,通过这种方式,我们可能会失去绳索结构所具有的O(1)连接可能性,使其降低到通常的O(log n),因此我们可能只使用了常规的treap一根绳子即使不是,也可以在节点中缓存整个子树的哈希值。

  3. 如果我们反转哈希多项式中的幂次序,则将其设为
    h(s [0] s [1] ... s [n-1])=(s [0] * p ^ 0 + s [1] * p ^ 1 + ... + s [n-1] * p ^(n-1))mod q,
    数学是相似的,但是从节点的所有正确后代收集哈希可以迭代而不是递归地完成。