2016-11-05 326 views

回答

1

這些財產是屬性的哈希函數。它有效地縮小了功能共域,增加了碰撞機會,所以看起來不太可能。

此外,this blog post提供一種逆變功能murmur哈希:

uint64 murmur_hash_64(const void * key, int len, uint64 seed) 
{ 
    const uint64 m = 0xc6a4a7935bd1e995ULL; 
    const int r = 47; 

    uint64 h = seed^(len * m); 

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

    while (data != end) 
    { 
#ifdef PLATFORM_BIG_ENDIAN 
     uint64 k = *data++; 
     char *p = (char *)&k; 
     char c; 
     c = p[0]; p[0] = p[7]; p[7] = c; 
     c = p[1]; p[1] = p[6]; p[6] = c; 
     c = p[2]; p[2] = p[5]; p[5] = c; 
     c = p[3]; p[3] = p[4]; p[4] = c; 
#else 
     uint64 k = *data++; 
#endif 

     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(data2[6]) << 48; 
    case 6: h ^= uint64(data2[5]) << 40; 
    case 5: h ^= uint64(data2[4]) << 32; 
    case 4: h ^= uint64(data2[3]) << 24; 
    case 3: h ^= uint64(data2[2]) << 16; 
    case 2: h ^= uint64(data2[1]) << 8; 
    case 1: h ^= uint64(data2[0]); 
     h *= m; 
    }; 

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

    return h; 
} 

uint64 murmur_hash_64_inverse(uint64 h, uint64 seed) 
{ 
    const uint64 m = 0xc6a4a7935bd1e995ULL; 
    const uint64 minv = 0x5f7a0ea7e59b19bdULL; // Multiplicative inverse of m under % 2^64 
    const int r = 47; 

    h ^= h >> r; 
    h *= minv; 
    h ^= h >> r; 
    h *= minv; 

    uint64 hforward = seed^(((uint64)8) * m); 
    uint64 k = h^hforward; 

    k *= minv; 
    k ^= k >> r; 
    k *= minv; 

#ifdef PLATFORM_BIG_ENDIAN 
    char *p = (char *)&k; 
    char c; 
    c = p[0]; p[0] = p[7]; p[7] = c; 
    c = p[1]; p[1] = p[6]; p[6] = c; 
    c = p[2]; p[2] = p[5]; p[5] = c; 
    c = p[3]; p[3] = p[4]; p[4] = c; 
#endif 

    return k; 
} 

可以作爲要與哈希值<2^32找到儘可能多的投入。

您對可靠性的問題並沒有太大的意義:你總是必須做好準備,妥善處理衝突。從我的練習中,我不建議使用普通整數或指針值作爲散列,因爲它們會產生不需要的模式。

相關問題