在 Java 中排序独立哈希

Order Independent Hash in Java

我想计算 Java 中一组字符串的哈希值。是的,我可以对字符串进行排序并计算 使用 digest.update 进行 MD5 哈希迭代。 但我更愿意省略排序并使用类似 combineUnordered https://github.com/google/guava/wiki/HashingExplained 有很多类似的问题问同样的问题,例如 但他们都没有提供一个简单的例子来展示如何在 Java.

中迭代计算一个独立于顺序的散列

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

这是一个示例(假设我们有一个方法 md5Hex(String str) 计算给定字符串的 md5 散列和 returns 十六进制格式的结果) :

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);

只需对每个散列进行 XOR,顺序无关紧要,而且散列大小将是固定的,而不是随着集合的大小而增长。

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

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

Hashcode 使用 guava 和 MD5 就像问的问题:

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;
}