2013-03-15 209 views
0

我需要使用現有的(C++)哈希函數爲給定的鍵創建32位哈希值。 該功能非常複雜。保留哈希值保留

現在我需要保留一個值,即散列函數永遠不會輸出這個值。

在沒有理解/改變現有散列函數的複雜邏輯的情況下,是否有安全的方法?

非常感謝......

回答

0

看起來你需要「可選」鍵。然後,您會怎麼做

hash = hash_combine(has_value()? 1 : 0, has_value()? hash(value()) : 0); 

或者,如果你堅持,你可以位的數量減少到31

compromised_hash = SHIFT_RIGHT(raw_hash)^raw_hash; // just an example. 

現在,MSB將永遠是空的。如果不是,你有你的特殊標記。這不會是容易使這使得它僅1元(除非你可以改變的哈希原函數)

+0

謝謝,好主意隨着轉移到31位,但第一個解決方案與可選鍵我不明白。 has_value()和value()做什麼? – 2013-03-15 16:43:16

+0

既然你沒有標記爲任何特定的語言,它是一個'可選'類型的僞代碼(我假設你可能想表示「沒有價值」作爲散列0,但實際上任何'特殊'的情況下可以處理方式相同)。 C++將有'boost :: optional',C#'System.Nullable '。等IOW:「特殊情況檢測」的例子 – sehe 2013-03-16 16:53:19

0

最簡單的方法,如果你想有一個哈希函數永遠不會返回零降低哈希域:

int result; 

hash = compute_hash_one_way(); // Hopefully it's not zero 
if (hash) return hash;   // In which case we return it 
hash = compute_hash_another_way(); // Try something else 
if (hash) return hash;    // If that was good, return that 
return 8675309; // We know THAT's not zero 

第二個散列計算不需要任何花哨;基本上,如果有一個可用的非零值取決於輸入,那麼最好使用它來優先返回一個常量,但最好使用一個非常糟糕的快速哈希函數(或甚至簡單地總是返回一個常量,如果原始返回零)比花費那麼多時間計算第二個散列,外部代碼可能會推斷原始散列爲零。請注意,如果原始散列值是好的,甚至當原始散列值返回零時返回一個常數值,只會導致該常量以20億分之一的輸入量返回,而不是40億分之一。如果我在.NET/Java中編寫了GetHashCode或hashcode的規範,我會強烈建議一個好的散列函數只能返回零,如果它基本上可以瞬間完成的話。所需的額外時間有Integer.GetHashCode()永遠不會返回零將在大多數情況下超過任何時候,可能會花費多餘的時間調用GetHashCode零值,但像一個字符串哈希返回零可以在某些情況下有重大性能影響。]