如果我的数学运算正确,如果我已经为每个字符串设置了单独的哈希值,我可以快速为两个字符串的串联生成新的哈希值。但是,只有散列函数具有以下形式:
hash(n) = k * hash(n-1) + c(n), and h(0) = 0.
在这种情况下,
hash( concat(s1,s2) ) = k**length(s2) * hash(s1) + hash(s2)
例如
h1 = makeHash32_SDBM( "abcdef", 6 );
h2 = makeHash32_SDBM( "ghijklmn", 8 );
h12 = makeHash32_SDBM( "abcdefghijklmn", 14 );
hx = mod32_powI( 65599, 8 ) * h1 + h2;
h1 = 2534611139
h2 = 2107082500
h12 = 1695963591
hx = 1695963591
Note that h12 = hx so this demonstrates the idea.
现在,对于SDBM hash
k=65599
。鉴于DJB hash
有k=33
(或可能是31
?)和h(0) = 5381
,为了使其有效,您可以设置h(0) = 0
。
但DJB hash
上的修改使用xor
代替+
来添加每个字符。
http://www.cse.yorku.ca/~oz/hash.html
如果哈希函数使用xor
而不是+
,是否还有另一种快速计算连接字符串哈希值的技术?
答案 0 :(得分:0)
如果您的第二个哈希将是哈希初始状态的函数,那将是真的。对于某些类型的散列函数,可以根据新的初始状态(如xor'e单词或其总和等)轻松移动它们。但一般情况下几乎不可能(在其他情况下,在密码匹配中使用hash +“salt”将更容易破解)。
但通常你可以使用第一个字符串的散列结果,然后继续从第二个字符串中提取数据。
更新:
我想无法找到f(x,y)
:
h_abc = hashOf(h0, "abc")
h_def = hashOf(h0, "def")
(h_abcdef = f(h_abc, h_def)) == hashOf(h0, "abcdef")
但你能够:
h_abc = hashOf(h1, "abc")
(h_abcdef = hashOf(h_abc, "def")) == hashOf(h0, "abcdef")
你不能这样做的原因之一是“33”不是“2”的力量。如果它将使用“32”(2 ** 5),那么:
h_abcdef == (h_abc << (5*len(abc))) xor h_def