Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/345.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
从几个Java字符串对象创建哈希_Java_Hash_Md5_Hashcode_Sha - Fatal编程技术网

从几个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在速度上相等)“真正的随机性”--这里没有发现这种情况。你很敏锐。改为“伪随机性”,我从一开始就是这么说的。