2010-10-20 41 views
1

我正在看MurmurHash(sites.google.com/site/murmurhash/) 我在黑盒中使用它的一種方式,而不是試圖瞭解在這個階段的數學。MurmurHash - 它如何通過密鑰循環?

不過,我也有在代碼稍微留意一下,並得到擔心似乎是如何工作的? 下面的代碼:

uint64_t MurmurHash64A (const void * key, int len, unsigned int seed) 
{ 
    const uint64_t m = 0xc6a4a7935bd1e995; 
    const int r = 47; 

    uint64_t h = seed^(len * m); 

    const uint64_t * data = (const uint64_t *)key; 
    const uint64_t * end = data + (len/8); 

    while(data != end) 
    { 
     uint64_t k = *data++; 

     k *= m; 
     k ^= k >> r; 
     k *= m; 

     h ^= k; 
     h *= m; 
    } 

    const unsigned char * data2 = (const unsigned char*)data; 

    switch(len & 7) 
    { 
    case 7: h ^= uint64_t(data2[6]) << 48; 
    case 6: h ^= uint64_t(data2[5]) << 40; 
    case 5: h ^= uint64_t(data2[4]) << 32; 
    case 4: h ^= uint64_t(data2[3]) << 24; 
    case 3: h ^= uint64_t(data2[2]) << 16; 
    case 2: h ^= uint64_t(data2[1]) << 8; 
    case 1: h ^= uint64_t(data2[0]); 
      h *= m; 
    }; 

    h ^= h >> r; 
    h *= m; 
    h ^= h >> r; 

    return h; 
} 

注意這是64位計算機的64位版本。 我的問題是,我不明白它是如何通過你發送的密鑰步驟。例如,如果我給它發送一個指向字符串「ABC」的指針。我可以看到我會發送一個指向第一個字符「A」的指針,長度爲3.我的有限C++知識告訴我它會創建一個指向與傳入位置相同的位置的指針「數據」指針。但是,在它中,通過取'數據'並將字符串的長度除以8來計算密鑰的結尾。 因此,如果密鑰小於8,while循環將不會被觸發,並且第一個一點數學的東西就會完成。有沒有人知道它爲什麼被8除?

是因爲第一個數學位只是意味着發生了8個以上的字符(如果有的話)爲什麼?

在此先感謝。 C

+0

我已經提出了Benoit的正確答案,但我確實想提到上面的代碼已經過時。 MurmurHash3提高了散列質量,速度更快。 – 2011-02-03 07:33:56

回答

3

算法一次處理通過8個字節的數據(uint64_t是8個字節)。 第一個循環將組合所有8個字節組成8個字節的單個密鑰。 然後交換機將使用剩餘的字節(在您的示例中,所有3個字節都通過「ABC」)並對其進行處理,以在最終結果中考慮到這些字節。

+0

非常感謝。 – Columbo 2010-10-20 15:40:13