用Java命令独立哈希

时间:2017-11-12 20:54:29

标签: java hash set unordered

我想在Java中计算一组字符串的哈希值。是的我可以对字符串进行排序并计算出来 使用digest.update进行MD5哈希迭代。 但我宁愿省略排序并使用combineUnordered https://github.com/google/guava/wiki/HashingExplained之类的内容 有许多类似的问题要求相同,例如Order-independant Hash Algorithm 但是没有它们提供了一个简单的例子,展示了如何在Java中计算迭代的顺序无关哈希。

2 个答案:

答案 0 :(得分:5)

只是对每个哈希和顺序进行异或,并且哈希大小将被修复,而不是随着集合的大小增长。

使用内置java字符串哈希码的Hashcode:

int hashcode = strings.stream()
        .mapToInt(Object::hashCode)
        .reduce(0, (left, right) -> left ^ right);

使用guava和MD5的Hashcode问题如下:

Optional<byte[]> hash = strings.stream()
        .map(s -> Hashing.md5().hashString(s, Charset.defaultCharset()))
        .map(HashCode::asBytes)
        .reduce((left, right) -> xor(left, right));


static byte[] xor(byte[] left, byte[] right) {
    if(left.length != right.length) {
        throw new IllegalArgumentException();
    }
    byte[] result = new byte[left.length];
    for(int i=0; i < result.length; i++) {
        result[i] = (byte) (left[i] ^ right[i]);
    }
    return result;
}

答案 1 :(得分:1)

您可以单独计算每个字符串的MD5哈希值,然后将它们全部添加以获得单个哈希值。这将是与订单无关的。因为加法运算是可交换的。

这是一个例子(假设我们有一个方法 md5Hex(String str),它计算给定字符串的md5哈希并以十六进制格式返回结果):

String[] strings = {"str1", "str2", "str3", ...};

BigInteger hashSum = BigInteger.ZERO;
for(String s : strings) {
    String hexHash = md5Hex(s);
    hashSum = hashSum.add(new BigInteger(hexHash, 16));
}

String finalHash = hashSum.toString(16);