我想把字符串哈希成一个int型,存储在数据库中,以前都是自己写的BKDRhash来实现的
现在换成C#之后,请问有类似的函数么?PS:貌似string的gethashcode方法只能保证在内存当中是唯一的,但是不能保证同一个字符串在两次调用gethashcode的时候始终得到同一个int谢了
现在换成C#之后,请问有类似的函数么?PS:貌似string的gethashcode方法只能保证在内存当中是唯一的,但是不能保证同一个字符串在两次调用gethashcode的时候始终得到同一个int谢了
这样的碰撞率会低于BDKRHASH等算法么?
这样的碰撞率会低于BDKRHASH等算法么?
这么说吧,如果你有2个不同的字符串,碰撞概率逼近1/42亿
时间: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); }
如果想自己写一个也很简单:public static int Hash(string str)
{
return str.Aggregate(0, (h, c) => unchecked(h * 131 + c));
}
md5不过是一个长整型,表示为字符串也不过是最多32位字母的。
你有没有证据表面:用长整型来索引比用string做索引快多少,你的程序的用户能体会到么?我看主要都是自己琢磨着的。
可是源代码明明是个确定性的算法啊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));
}
}
以下摘自微软string.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));
}
}
我之前也是以为是确定的,但是后来我DEBUG的时候发现同一个字符串,运行多次程序的时候,得到的hash值不一样,后来网上搜索了一下,发现gethashcode只能保证在当前应用程序中保证唯一。其实想也想得到,string的组合是无限的,int型就那么几十亿,不可能作为唯一性。但是如果在当前应用程序中,由于内存是有限的,string的组合也变成了有限的,int型的几十亿就可以保证hash值的唯一性了
md5不过是一个长整型,表示为字符串也不过是最多32位字母的。
你有没有证据表面:用长整型来索引比用string做索引快多少,你的程序的用户能体会到么?我看主要都是自己琢磨着的。MD5是长整型,但是存在数据库里面是用varchar存的啊,比较一个32字节的MD5从原理上肯定没有比较一个4字节的int快吧。而且数据库对于varchar和int的优化也不一样。
我对于唯一性的需求不仅仅是对于当前程序,我的需求是运行每次程序,对于同一个字符串都能得到相同的hash值,这个hash值可以有碰撞,但是必须在多次运行程序的情况下是相同的。
你这个方法还要和DateTime.Now.Ticks关联,不能达到我的效果吧
以前是用的自己的BDKRHASH,当然我现在也可以自己改写一下这个函数,然后继续使用,我只是想知道有没有类似的函数而已
我不是要随机字符串转int,请看清楚我的问题再回答
如果你要用MD5转,参考上贴如果你想用MD5的一部分转int64,参考18楼。你要擅长举一反三,而不是等着别人给你写代码。如果你想研究不同的hash算法,看下帖的评论
http://blog.csdn.net/wwwsq/article/details/1526595