2013-03-15 105 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零值,但像一个字符串哈希返回零可以在某些情况下有重大性能影响。]