在数据库中存储C#GetHashCode()不可靠

sis*_*dog 5 c# regex sql-server hash gethashcode

可能的重复:
如何在.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. 有没有比使用散列算法更好的字符串压缩算法?

谢谢

令人敬畏的回应有很多。非常感谢你!!!

kpr*_*bst 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();
}
Run Code Online (Sandbox Code Playgroud)

像这样称呼它:

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

并得到:

> 777BED7F83C66DAC111977067B4B4385
Run Code Online (Sandbox Code Playgroud)

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

唯一的问题是使用这样的字符串作为表上的主键可能会在性能方面出现问题。

您可以做的另一件事是使用 URL 缩短方法:使用数据库的序列生成功能,并将值(确保您使用 LONG 或 BIGINT 的等效项!)转换为 Base36 之类的内容,这将为您提供一个漂亮、简洁的字符串。