如何快速哈希URL

时间:2011-10-18 15:31:28

标签: c# algorithm c#-4.0 hash

我有一个独特的情况,我需要动态产生哈希。这是我的情况。此问题与here有关。我需要在数据库中存储许多需要编制索引的URL。一个URL可以超过2000个字符。数据库抱怨超过900字节的字符串无法编入索引。我的解决方案是使用MD5或SHA256散列URL。我不确定使用哪种哈希算法。这是我的要求

  • 最短的角色长度,最小的碰撞
  • 需要非常快速。我将在每个页面请求中散列引用
  • 碰撞需要最小化,因为我的数据库中可能有数百万个网址

我并不担心安全问题。我担心角色长度,速度和碰撞。有人知道这个算法很好吗?

7 个答案:

答案 0 :(得分:1)

在你的情况下,我不会使用任何加密哈希函数(即MD5,SHA),因为它们在设计时考虑了安全性:它们主要是想尽可能地使用它来创建两个不同的字符串相同的哈希。我认为这不会是你的问题。 (随机碰撞的可能性当然是散列所固有的)

强烈建议使用String.GetHashCode(),因为实现未知,MSDN表示它可能因框架的不同版本而异。甚至x86和x64版本之间的结果也可能不同。因此,当您尝试使用较新(或不同)版本的.NET框架访问同一数据库时,您会遇到麻烦。

我在维基百科(here)上找到了hashCode的Java实现算法,它似乎很容易实现。即使是简单的实现也会比MD5或SHA imo的实现更快。您还可以使用long值来降低碰撞的可能性。

还有对.NET GetHashCode实现here的简短分析(不是算法本身,而是一些实现细节),我猜你也可以使用这个。 (或尝试以类似的方式实现Java版本......)

答案 1 :(得分:0)

我建议使用System.Security.Cryptography.SHA1Cng课程。它是160位或20字节长,因此它应该足够小。如果你需要它是一个字符串,它只需要40个字符,所以这应该很适合你的需要。它也应该足够快,据我所知,还没有发现碰撞。

答案 2 :(得分:0)

我个人使用String.GetHashCode()。这是基本的哈希函数。老实说,与其他实现相比,我不知道它的表现如何,但应该没问题。

您命名的两个散列函数中的任何一个都应该足够快,以至于您不会注意到它们之间的差异。除非这个网站需要超高性能,否则我不会太担心它们。我个人可能会选择MD5。这可以格式化为64个字符的十六进制字符串或44个字符的基本64字符串。

我选择MD5的原因是因为你不太可能遇到冲突,即使你这样做,你也可以使用“where urlhash = @hash和url = @url”构建你的查询。数据库引擎应该确定一个是索引的而另一个不是索引,并使用该信息进行合理的搜索。

如果存在合并,则urlhash上的索引扫描将返回一些结果,这些结果很容易进行文本比较以获得正确的结果。但这不太可能经常发生。你以这种方式获得碰撞的可能性很小。

答案 3 :(得分:0)

快点:

URLString.GetHashCode().ToString("x")

答案 4 :(得分:0)

虽然MD5和SHA1都被证明无效,但防撞是必不可少的,我怀疑你的应用是否足够。我不确定,但我怀疑MD5会更简单,更快捷。

答案 5 :(得分:0)

.net 4.0中反映了GetHashCode函数的源代码

public override unsafe int GetHashCode()
{
    fixed (char* str = ((char*) this))
    {
        char* chPtr = str;
        int num = 0x15051505;
        int num2 = num;
        int* numPtr = (int*) chPtr;
        for (int i = this.Length; i > 0; i -= 4)
        {
            num = (((num << 5) + num) + (num >> 0x1b)) ^ numPtr[0];
            if (i <= 2)
            {
                break;
            }
            num2 = (((num2 << 5) + num2) + (num2 >> 0x1b)) ^ numPtr[1];
            numPtr += 2;
        }
        return (num + (num2 * 0x5d588b65));
    }
}

存在O(n)个简单运算(+,&lt;&lt;,^)和一个乘法。所以这很快。

我在3毫升DB上测试了这个功能,包含长度不超过256个字符的字符串,大约97%的字符串没有冲突。 (最多5个字符串具有相同的哈希值)

答案 6 :(得分:0)

您可能需要查看以下项目:

CMPH - C Minimal Perfect Hashing Library

查看以下热门话题列表中的完美哈希:

Hottest 'perfect-hash' Answers - Stack Overflow

您还可以考虑在SQL中使用全文索引而不是哈希:

CREATE FULLTEXT INDEX (Transact-SQL)