在 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;
}
我想计算 Java 中一组字符串的哈希值。是的,我可以对字符串进行排序并计算
使用 digest.update
进行 MD5 哈希迭代。
但我更愿意省略排序并使用类似 combineUnordered
https://github.com/google/guava/wiki/HashingExplained
有很多类似的问题问同样的问题,例如
您可以单独计算每个字符串的 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;
}