创建用于数据库的哈希码(即不使用GetHashCode)

我最近接受了GetHashCode()方式的指示,特别是“GetHashCode的消费者不能依赖它随时间推移或跨appdomains稳定”(来自Eric Lippert博客文章 )。

不幸的是,我一直在数据库中使用它来尝试加速查找(通过插入GetHashCode的结果而不是对文本字符串进行搜索)。 我现在意识到这是一件非常糟糕的事情。

所以我想知道我能做些什么呢。 是否有任何给定字符串将保证返回一个合理的抗冲突整数,我可以用于查找?

我可以自己写一些东西,但我希望有一些内置的东西,我可以使用,而不必去加密库中的东西,感觉有点重量级。

我鼓励你考虑其他人所说的话:让数据库做它擅长的事情。 创建哈希代码以优化查找表明您的表上的索引不是它们应该的。

也就是说,如果你真的需要一个哈希码:

您没有说是否需要32位或64位哈希码。 这个将为字符串创建64位哈希码。 它具有合理的抗碰撞性。

public static long ComputeHashCode(string url) { const ulong p = 1099511628211; ulong hash = 14695981039346656037; for (int i = 0; i < url.Length; ++i) { hash = (hash ^ url[i]) * p; } // Wang64 bit mixer hash = (~hash) + (hash << 21); hash = hash ^ (hash >> 24); hash = (hash + (hash << 3)) + (hash << 8); hash = hash ^ (hash >> 14); hash = (hash + (hash << 2)) + (hash << 4); hash = hash ^ (hash >> 28); hash = hash + (hash << 31); if (hash == (ulong)UNKNOWN_RECORD_HASH) { ++hash; } return (long)hash; } 

请注意,这是一个哈希码,如果您有多达数十亿条记录,则冲突的可能性非常小。 经验法则:当项目数超过哈希码范围的平方根时,您有50%的碰撞几率。 此哈希码的范围为2 ^ 64,因此如果您有2 ^ 32项,则碰撞的几率约为50%。

有关详细信息,请参阅http://www.informit.com/guides/content.aspx?g=dotnet&seqNum=792和http://en.wikipedia.org/wiki/Birthday_paradox#Probability_table 。

正如SLaks在评论中指出的那样,查找数据是数据库擅长的。

如果需要快速查找,请在列上创建索引。 至少,你不必再处理碰撞了。

你在使用MSSQL数据库吗? T-SQL Checksumfunction正是如此。