5

可能重复:
如何在 .net (c#) 中为可安全存储在数据库中的字符串创建 HashCode?

我计划在我的数据库中存储数十万个 URL。我的 UrlInfo 表中的每一行都是不可变的,而 URL 本身就是逻辑主键。由于 URL 可能相当长,因此我决定对 URL 进行哈希处理,以便在添加新行时快速找到可能的匹配项。哈希不是我真正的关键,只是一种快速找到可能匹配项的方法。此外,我使用每个域的 RegEx 模式,将 URL 的本质提炼成可以与其他 URL 进行比较的东西。我将 RegEx 的结果也存储为哈希,我不担心它是否会产生可能的重复项。

一切都很顺利,直到我了解到 C# 的 string.GetHashCode() 方法(我一直用来散列事物)不能保证在 .Net 的实现中是唯一的。当我尝试将哈希函数从 ASP.Net 移动到 SQLServer CLR 代码时,我注意到了这一点。Web 应用程序使用 .Net 4.0,我了解到,SQLServer 2008 R2 使用 .Net 3.5。他们为相同的字符串产生了单独的哈希结果,所以现在我需要摆脱使用 string.GetHashCode() ,因为当我将应用程序升级到未来版本的 .Net 时,我不想担心这种变化。

所以,问题:

  1. 自从我在我的数据库中存储哈希后,我的架构是否有异味?还有更好的方法吗?显然微软不希望我存储哈希结果!

  2. 有人可以推荐一个好的 C# 替换算法来散列字符串吗?我在这里看到了 Jon,但不确定如何修改以适用于字符串(使用 ascii 代码循环遍历每个字符?)。

  3. 有没有比使用哈希算法更好的字符串压缩算法?

谢谢

许多人的反应很棒。非常感谢你!!!

4

5 回答 5

3

您总是可以使用 MD5 散列,这相对较快:

public string GetUrlHash(string url) {

    byte[] hash = MD5.Create().ComputeHash(Encoding.UTF8.GetBytes(url));

    StringBuilder sb = new StringBuilder();
    for (int i = 0; i < hash.Length; i++) {
        sb.Append(hash[i].ToString("X2"));
    }

    return sb.ToString();
}

像这样称呼它:

Console.WriteLine(this.GetUrlHash("http://stackoverflow.com/questions/5355003/storing-c-gethashcode-in-db-is-unreliable"));

并得到:

> 777BED7F83C66DAC111977067B4B4385

从唯一性的角度来看,这应该是相当可靠的。如今,MD5 对于密码应用程序来说是不安全的,但您在这里没有这个问题。

The only problem is using a string like this as a primary key on a table might be problematic, performance-wise.

The other thing you could do is use the URL shortener approach: use your database's sequence generation feature, and convert the value (make sure you use the equivalent of LONG or BIGINT!) to something like Base36, which gives you a nice, concise string.

于 2011-03-18T16:47:54.433 回答
1

这里也问了一个类似的问题:

如何在 .net (c#) 中为可安全存储在数据库中的字符串创建 HashCode?

它可能证明可以解决您的问题。

于 2011-03-18T16:34:06.847 回答
1

As a note, SQL Server from 2008 supports (has) the function HASHBYTES, that given some data (a string for example) can generate a MD2, MD4, MD5, SHA or SHA1 hash.

于 2011-03-18T16:48:13.623 回答
0

I'd say you probably don't need to store the hash.

Just make sure that you correctly index the URL column in your table (a unique index) and the searches should be fast.

于 2011-03-18T16:56:24.990 回答
0

Have you considered zipping down your string and storing a VARBINARY? It could be much smaller, you could build an index directly on it.

于 2011-03-18T18:35:49.047 回答