【问题标题】:How to quickly generate a new string hash after concatenating 2 strings连接2个字符串后如何快速生成新的字符串哈希
【发布时间】:2010-04-04 10:24:26
【问题描述】:

如果我的数学是正确的,如果我已经拥有每个字符串的单独哈希值,我可以快速为两个字符串的连接生成一个新的哈希值。但前提是散列函数的形式为:

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而不是+,是否有另一种技术可以快速计算连接字符串的哈希值?

【问题讨论】:

    标签: hash string-concatenation


    【解决方案1】:

    如果您的第二个散列将是散列初始状态的函数,那将是正确的。对于某些类型的散列函数,很容易根据新的初始状态(如异或词或它们的总和等)来转移它们。但在一般情况下,这几乎是不可能的(在其他情况下,在密码匹配中使用 hash+"salt" 会更容易破解)。

    但通常你可以使用第一个字符串的散列结果,而不是继续从第二个字符串提供数据。

    更新:
    我想没有办法找到f(x,y) for:

    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
    

    【讨论】:

    • 我想你是说一般情况是从第一个字符串的哈希开始并将其视为 h(0),然后输入第二个字符串的每个字符以生成新的散列。
    • @philcolbourn,只是不要丢弃计算第一个字符串的哈希值的中间对象,您将能够继续更新该对象以获取两个字符串的哈希值。我见过的大多数散列函数接口在为已经提供的数据生成 散列结果 后都能够继续进行。
    • 在这些情况下,我的中间对象是哈希值,但是对于使用 xor 的乘法哈希是否有一个神奇的公式?
    • 请注意我所希望的,但您已经回答了这个问题。我认为 len(abc) 应该是 len(def) 但在你的例子中这并不重要,因为两者都是 3。
    猜你喜欢
    • 2014-03-26
    • 2012-03-07
    • 1970-01-01
    • 1970-01-01
    • 2012-03-21
    • 1970-01-01
    • 1970-01-01
    • 2018-06-22
    • 2012-11-14
    相关资源
    最近更新 更多