对于C ++,我一直在使用Boost.Functional/Hash创建好的哈希值,而不必处理位移,异或和素数。是否有任何库为C#/ .NET产生良好的(我不是要求最佳)哈希值?我会使用此实用程序来实现GetHashCode(),而不是加密哈希。
为了澄清为什么我认为这是有用的,这里是boost::hash_combine
的实现,它结合了哈希值(当然是实现GetHashCode()时非常常见的操作):
seed ^= hash_value(v) + 0x9e3779b9 + (seed << 6) + (seed >> 2);
显然,这类代码不属于GetHashCode()
的实现,因此应该在其他地方实现。
答案 0 :(得分:4)
我不会仅仅为此使用单独的库。如前所述,对于GetHashCode
方法,快速稳定至关重要。通常我更喜欢编写内联实现,但实际上使用辅助类可能是个好主意:
internal static class HashHelper
{
private static int InitialHash = 17; // Prime number
private static int Multiplier = 23; // Different prime number
public static Int32 GetHashCode(params object[] values)
{
unchecked // overflow is fine
{
int hash = InitialHash;
if (values != null)
for (int i = 0; i < values.Length; i++)
{
object currentValue = values[i];
hash = hash * Multiplier
+ (currentValue != null ? currentValue.GetHashCode() : 0);
}
return hash;
}
}
}
这种方式可以使用常见的哈希计算逻辑:
public override int GetHashCode()
{
return HashHelper.GetHashCode(field1, field2);
}
答案 1 :(得分:1)
除非您有非常具体的要求,否则您不需要从第一原则计算类型的哈希码。而是以一种简单的方式组合用于确定相等性的字段/属性的哈希码,例如:
int hash = field1.GetHashCode();
hash = (hash *37) + field2.GetHashCode();
(组合函数取自§3.3.2C# in Depth, 2nd Ed, Jon Skeet)。
答案 2 :(得分:1)
this question的答案包含一些类似于Boost.Functional / Hash的辅助类的示例。但是,没有一个看起来很优雅。
我不知道有任何真正的.NET库提供等效的。
答案 3 :(得分:0)
要避免装箱问题,请使用Int32上的通用扩展方法链接您的调用
public static class HashHelper
{
public static int InitialHash = 17; // Prime number
private static int Multiplier = 23; // Different prime number
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Int32 GetHashCode<T>( this Int32 source, T next )
{
// comparing null of value objects is ok. See
// http://stackoverflow.com/questions/1972262/c-sharp-okay-with-comparing-value-types-to-null
if ( next == null )
{
return source;
}
unchecked
{
return source + next.GetHashCode();
}
}
}
然后你可以做
HashHelper
.InitialHash
.GetHashCode(field0)
.GetHashCode(field1)
.GetHashCode(field2);
答案 4 :(得分:-3)
看一下这个link,它描述了MD5哈希。 否则使用GetHashCode()。