我想把字符串哈希成一个int型,存储在数据库中,以前都是自己写的BKDRhash来实现的
现在换成C#之后,请问有类似的函数么?PS:貌似string的gethashcode方法只能保证在内存当中是唯一的,但是不能保证同一个字符串在两次调用gethashcode的时候始终得到同一个int谢了

解决方案 »

  1.   

    用int表示string的Hash,碰撞率很高的。你想,整数只能表示42亿个不同的组合(全部由数字构成的字符串也就是9位),而字符串可以有比这个大很多的组合。
      

  2.   

    MD5,SHA2这些虽然不会碰撞,但是开销也大啊。而且为了加快在数据库中的查询速度,我打算把hash之后的值作为索引,用MD5值作为索引没有int作为索引查询的速度快啊
      

  3.   

    你可以算出MD5,取最后32位,作为Hash。
      

  4.   

    你可以算出MD5,取最后32位,作为Hash。
    这样的碰撞率会低于BDKRHASH等算法么?
      

  5.   

    你可以算出MD5,取最后32位,作为Hash。
    这样的碰撞率会低于BDKRHASH等算法么?
    这么说吧,如果你有2个不同的字符串,碰撞概率逼近1/42亿
      

  6.   

    C#生成唯一的字符串或者数字
    时间:2012-09-25 11:19来源:未知 作者:admin 点击:201次我要投稿  高质量的ASP.NET空间,完美支持1.0/2.0/3.5/4.0/MVC等当我们想要获得一个唯一的key的时候,通常会想到GUID。这个key非常的长,虽然我们在很多情况下这并不是个问题。但是当我们需要将这个36个字符的字符串放在URL中时,会使的URL非常的丑陋。      想要缩短GUID的长度而不牺牲它的唯一性是不可能的,但是如果我们能够接受一个16位的字符串的话是可以做出这个牺牲的。      我们可以将一个标准的GUID 21726045-e8f7-4b09-abd8-4bcc926e9e28  转换成短的字符串 3c4ebc5f5f2c4edc      下面的方法会生成一个短的字符串,并且这个字符串是唯一的。重复1亿次都不会出现重复的,它也是依照GUID的唯一性来生成这个字符串的。
       private string GenerateStringID()        {            long i = 1;            foreach (byte b in Guid.NewGuid().ToByteArray())            {                i *= ((int)b + 1);            }            return string.Format("{0:x}", i - DateTime.Now.Ticks);        } 
     如果你想生成一个数字序列而不是字符串,你将会获得一个19位长的序列。下面的方法会把GUID转换为Int64的数字序列。
      private long GenerateIntID()        {            byte[] buffer = Guid.NewGuid().ToByteArray();            return BitConverter.ToInt64(buffer, 0);        }
      

  7.   

    用MD5不错,是一种标准。
    如果想自己写一个也很简单:public static int Hash(string str)
    {
        return str.Aggregate(0, (h, c) => unchecked(h * 131 + c)); 
    }
      

  8.   


    md5不过是一个长整型,表示为字符串也不过是最多32位字母的。
    你有没有证据表面:用长整型来索引比用string做索引快多少,你的程序的用户能体会到么?我看主要都是自己琢磨着的。
      

  9.   

    不知道楼主的结论是如何得出的?
    可是源代码明明是个确定性的算法啊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));
        }
    }
      

  10.   

    因为微软不给保证:)
    以下摘自微软string.GetHashCode的参考:
      

  11.   

    那也可以直接COPY修改某个版本的GetHashCode,用不着到处找了吧
      

  12.   

    不知道楼主的结论是如何得出的?
    可是源代码明明是个确定性的算法啊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));
        }
    }
    我之前也是以为是确定的,但是后来我DEBUG的时候发现同一个字符串,运行多次程序的时候,得到的hash值不一样,后来网上搜索了一下,发现gethashcode只能保证在当前应用程序中保证唯一。其实想也想得到,string的组合是无限的,int型就那么几十亿,不可能作为唯一性。但是如果在当前应用程序中,由于内存是有限的,string的组合也变成了有限的,int型的几十亿就可以保证hash值的唯一性了
      

  13.   


    md5不过是一个长整型,表示为字符串也不过是最多32位字母的。
    你有没有证据表面:用长整型来索引比用string做索引快多少,你的程序的用户能体会到么?我看主要都是自己琢磨着的。MD5是长整型,但是存在数据库里面是用varchar存的啊,比较一个32字节的MD5从原理上肯定没有比较一个4字节的int快吧。而且数据库对于varchar和int的优化也不一样。
      

  14.   


    我对于唯一性的需求不仅仅是对于当前程序,我的需求是运行每次程序,对于同一个字符串都能得到相同的hash值,这个hash值可以有碰撞,但是必须在多次运行程序的情况下是相同的。
    你这个方法还要和DateTime.Now.Ticks关联,不能达到我的效果吧
      

  15.   

    MD5是16字节或者32字节,存在数据库里面就要用varchar类型了,我想要hash成int或者long类型,有碰撞可以允许,只要碰撞率不高即可。
    以前是用的自己的BDKRHASH,当然我现在也可以自己改写一下这个函数,然后继续使用,我只是想知道有没有类似的函数而已
      

  16.   

    字符串转int64 byte[] buffer = Guid.NewGuid().ToByteArray();            return BitConverter.ToInt64(buffer, 0);
      

  17.   


    我不是要随机字符串转int,请看清楚我的问题再回答
      

  18.   

    http://blog.sina.com.cn/s/blog_64492fe10100supc.html
    如果你要用MD5转,参考上贴如果你想用MD5的一部分转int64,参考18楼。你要擅长举一反三,而不是等着别人给你写代码。如果你想研究不同的hash算法,看下帖的评论
    http://blog.csdn.net/wwwsq/article/details/1526595