2013-07-02 52 views
6

我使用boost::hash來獲取字符串的散列值。 但它給Windows 32位和Debian 64位系統上的相同字符串提供不同的哈希值。從boost :: hash獲取32位散列值

那麼我怎樣才能得到相同的散列值(32位或64位)使用boost::hash而不考慮平臺?

+0

可以想像,如果你依賴總是讓會發生什麼相同的哈希和提升會稍微改變他們的算法? –

+0

@Mark B,可能會導致可移植性問題。您可能希望在最簡單的情況下將來自不同平臺的散列字符串收集到一個數據結構中,並且存儲桶分佈是隨機的 –

+1

在您使用unicode的實例之一中,而在另一個實例中可能沒有? – Bee

回答

4

關於boost::hash的保證是什麼?我沒有看到任何 保證生成的哈希碼可用於生成它的 進程之外。 (這通常是 哈希函數的情況。)如果您需要外部數據的哈希值, 在不同的程序和不同的平臺上有效(例如 哈希存取磁盤上的數據),那麼您必須寫入擁有你的 。喜歡的東西:

uint32_t 
hash(std::string const& key) 
{ 
    uint32_t results = 12345; 
    for (auto current = key.begin(); current != key.end(); ++ current) { 
     results = 127 * results + static_cast<unsigned char>(*current); 
    } 
    return results; 

} 

應該做的伎倆,只要你不擔心 移植到一些異國情調的大型機(這可能不支持 uint32_t)。

0

使用一些衆所周知的通用散列函數(如SHA)代替,因爲這些函數應該保證相同的字符串在任何地方都具有相同的散列。請注意,如果你正在做一些與安全相關的事情,SHA可能太快了。這是一件奇怪的事情,但有時候快速並不意味着好,因爲它可能導致暴力破解 - 在這種情況下,還有其他的較慢的散列函數,其中一些函數基本上連續多次重複應用SHA 。另一件事,如果你在哈希密碼,記得要鹽(我不會詳細介紹,但信息很容易在線訪問)。

+2

自從他問'boost :: hash'時,我懷疑他擔心密碼安全性。對於數據訪問的哈希算法來說,SHA的速度遠遠不夠,而且它生成的哈希有足夠的位數,因此需要一個大數字包來對其進行模數運算,從而將其降低到範圍內。 –

+0

同意,謝謝。 – user2520968

0

上面的散列函數很簡單,但是很脆弱。

例如,傳遞給那個函數字符串,如「bb」「bbbb」「bbddbb」「ddffbb」 - 任何偶數符號與偶數ASCII碼的組合,並監視低位字節。 它總是將是57

相反,我建議用我的哈希函數,這是相對輕便, 並沒有容易的漏洞:

#define NLF(h, c) (rand[(uint8_t)(c^h)]) 
uint32_t rand[0x100] = { 256 random non-equal values }; 

uint32_t oleg_h(const char *key) { 
    uint32_t h = 0x1F351F35; 
    char c; 
    while(c = *key++) 
    h = ((h >> 11) | (h << (32 - 11))) + NLF(h, c); 
    h ^= h >> 16; 
    return h^(h >> 8); 
}