从几个Java字符串对象创建哈希
对于实现这样的方法,什么是最快和更健壮的(就唯一性而言)方法从几个Java字符串对象创建哈希,java,hash,md5,hashcode,sha,Java,Hash,Md5,Hashcode,Sha,对于实现这样的方法,什么是最快和更健壮的(就唯一性而言)方法 public abstract String hash(String[] values); values[]数组有100到1000个成员,每个成员都有几十个字符,每次需要在不同的values[]数组上以大约10000次/秒的速度运行该方法 是应该使用StringBuilder缓冲区生成长字符串,然后对缓冲区内容调用哈希方法,还是最好继续从值[]为每个字符串调用哈希方法 显然,至少需要64位的散列(例如MD5)来避免冲突,但是在相同的
public abstract String hash(String[] values);
values[]
数组有100到1000个成员,每个成员都有几十个字符,每次需要在不同的values[]
数组上以大约10000次/秒的速度运行该方法
是应该使用StringBuilder
缓冲区生成长字符串,然后对缓冲区内容调用哈希方法,还是最好继续从值[]
为每个字符串调用哈希方法
显然,至少需要64位的散列(例如MD5)来避免冲突,但是在相同的质量下,有没有更简单更快的方法呢
比如说,你呢
public String hash(String[] values)
{
long result = 0;
for (String v:values)
{
result += v.hashCode();
}
return String.valueOf(result);
}
由于纯加法的线性特性,绝对不要使用它,但您可以稍微修改代码以获得非常好的分散性
public String hash(String[] values) {
long result = 17;
for (String v:values) result = 37*result + v.hashCode();
return String.valueOf(result);
}
首先,散列码通常是数字的,例如
int
。此外,您的hash函数版本创建int,然后使其字符串表示形式IMHO没有任何意义
我将改进您的哈希方法,如下所示:
public int hash(String[] values) {
long result = 0;
for (String v:values) {
result = result * 31 + v.hashCode();
}
return result;
}
查看在类
java.lang.String
中实现的hashCode()
,在组合方法时,您应该注意创建弱点。(java哈希函数和您自己的)。我对级联密码做了一些研究,这就是一个例子。(添加可能会干扰hashCode()的内部
hashCode()的内部结构如下所示:
for (int i = 0; i < len; i++) {
h = 31*h + val[off++];
}
long hash = 0xCBF29CE484222325L;
for(String s : strings)
{
hash ^= s.hashCode();
hash *= 0x100000001B3L;
}
^这不是FNV的实际实现,因为它以INT而不是字节作为输入,但我认为它也可以工作。它不提供64位哈希,但考虑到问题的标题,可能值得一提的是,因为Java 1.7已经存在。下面是使用Java 7提供的Object类的简单实现。
@Override
public int hashCode()
{
return Objects.hash(this.variable1, this.variable2);
}
这种方法看起来很合理。您可能希望将散列值存储在字段中,这样就不必每次都重新计算散列值,只要您在字符串[]每次更改时都更新散列值即可。当然可以,但在有问题的应用程序中,值[]数组一直在更改。:-)足够17,或者需要更长的素数?那么,跨越数千万次调用的冲突又如何呢?无论你如何改变它,冲突都是不可避免的。如果是这样的问题,你应该使用更强的并且超过64位的。我同意,但是返回类型是一种应用程序形式。除此之外,你的建议与马尔科的类似。对于跨越数千万次调用的冲突,这可以吗?@MarkoTopolnik为什么这是一个问题?嗯。。。你确定这比这里建议的其他简单方法更快吗?从外观上看,随机性可能更好。我从未声称它比其他任何东西都快。事实上,速度与其他答案相同。(假设加法和xor在速度上相等)“真正的随机性”--这里没有发现这种情况。你很敏锐。改为“伪随机性”,我从一开始就是这么说的。