我必须在以下两个条件下编写一个哈希函数:
Object o
一无所知 - 它可以是String,Integer或实际的自定义对象; hashCode()
。我正在使用的方法,计算哈希码:
循环遍历字节数组并通过执行以下操作来计算哈希:
hash = hash * PRIME + byteArray [i]
我的问题是它是一种可行的方法,有没有办法改善它?就个人而言,我觉得这个功能的范围太广了 - 没有关于对象是什么的信息,但在这种情况下我几乎没有发言权。
答案 0 :(得分:3)
您可以使用HashCodeBuilder.reflectionHashCode而不是实施自己的解决方案。
答案 1 :(得分:1)
序列化方法仅适用于实际上可序列化的对象。因此,对于所有类型的对象实际上是不可能的。
此外,这会比较的对象具有等效的对象图,这与等于.equals()
不一定相同。
例如,由相同代码(具有相同数据)创建的StringBuilder对象将具有相等的OOS输出(即也等于散列),而b1.equals(b2)
为假,并且具有相同元素的ArrayList和LinkedList将是注册为不同,list1.equals(list2)
为true
。
您可以通过创建自定义HashOutputStream
来避免将字节流转换为数组步骤,该自定义class HashOutputStream extends OutputStream {
private static final int PRIME = 13;
private int hash;
// all the other write methods delegate to this one
public void write(int b) {
this.hash = this.hash * PRIME + b;
}
public int getHash() {
return hash;
}
}
只是获取字节数据并对其进行哈希处理,而不是将其保存为数组以供以后迭代
y = y*13 + x
然后将ObjectOutputStream包装在此类的对象周围。
您可以查看其他校验和算法,而不是Adler32
方法。例如,java.util.zip包含zlib
(以CRC32
格式使用)和gzip
(以{{1}}格式使用)。
答案 2 :(得分:0)
hash =(hash * PRIME + byteArray [i])%MODULO?
答案 3 :(得分:0)
此外,当你遇到它时,如果你想尽可能避免冲突,你可以在步骤3中使用标准化(加密,如果有意碰撞是一个问题)哈希函数,就像SHA-2一样?
看一下DigestInputStream
,这也让你不用第2步。
答案 4 :(得分:0)
在非加密散列上查看Bob Jenkin's article。他介绍了一些方法,并讨论了它们在速度和碰撞概率之间的优势,劣势和权衡。
如果不出意外,它将允许您证明您的算法决策是正确的。向你的导师解释为什么你选择速度超过正确性,反之亦然。
作为起点,试试他的One-at-a-time hash:
ub4 one_at_a_time(char *key, ub4 len)
{
ub4 hash, i;
for (hash=0, i=0; i<len; ++i)
{
hash += key[i];
hash += (hash << 10);
hash ^= (hash >> 6);
}
hash += (hash << 3);
hash ^= (hash >> 11);
hash += (hash << 15);
return (hash & mask);
}
这很简单,但对于更复杂的算法却非常出色。