0

在我们的应用程序中,我们从 java 对象生成哈希码并将其存储在数据库中的某个级别。现在我的问题是,如果有人手动生成一个数字,有没有办法我可以找出它是否是由 JVM 从对象创建的有效哈希码,而不是手动创建的。

4

4 回答 4

3

不,没有——至少如果它在int. 任何int 都是有效的哈希码。特别是,对于任何 int 值 x, 的哈希值new Integer(x) == x

然而,我想说的是,存储对象的 Java 哈希码通常不是一个好主意——如果哈希算法被指定并且永远不会改变,那也没关系——但否则当算法改变时你会自找麻烦您的哈希不再匹配。

于 2009-09-16T14:31:42.450 回答
3

如果您想在数据库中保留对象的“签名”,请使用不同的功能。hashCode 的设计目的不是难以猜测或逆向工程。

由于您使用了 hashCode,我假设您不关心具有相同的 F(X) = F(Y) ,其中 X 和 Y 是不同的对象。

如果确实如此,请考虑使用散列函数,也许再加上一些“秘密”盐。例如:

public static String signature(Object o)
{
    StringBuffer sb = new StringBuffer();
    try
    {
        MessageDigest md5 = MessageDigest.getInstance("md5");
        String st = "SECRET!!1" + o.hashCode();
        md5.update(st.getBytes());
        sb.append(getHexString(md5.digest()));
    }
    catch (NoSuchAlgorithmException e)
    {
        throw new RuntimeException("bah");
    }
    catch (UnsupportedEncodingException e)
    {
        throw new RuntimeException("bah2");
    }
    return sb.toString();
}

static final byte[] HEX_CHAR_TABLE =
{
        (byte) '0', (byte) '1', (byte) '2', (byte) '3', 
        (byte) '4', (byte) '5', (byte) '6', (byte) '7', 
        (byte) '8', (byte) '9', (byte) 'a', (byte) 'b',
        (byte) 'c', (byte) 'd', (byte) 'e', (byte) 'f'
};

public static String getHexString(byte[] raw) throws UnsupportedEncodingException
{
    byte[] hex = new byte[2 * raw.length];
    int index = 0;

    for (byte b : raw)
    {
        int v = b & 0xFF;
        hex[index++] = HEX_CHAR_TABLE[v >>> 4];
        hex[index++] = HEX_CHAR_TABLE[v & 0xF];
    }
    return new String(hex, "ASCII");
}
于 2009-09-16T14:45:37.850 回答
1

不。基本的 hashCode() 操作可以自由返回任何 int,只要它是一致的。我认为真正的问题是你想做什么?

于 2009-09-16T14:32:36.957 回答
1

没有办法找到这个。

于 2009-09-16T15:16:13.487 回答