2009-09-16 43 views
0

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

+0

不这么认为。你甚至可以重写默认的哈希码实现,但是你永远不会知道它是否是由你的代码(或者JVM)创建的或者是由手工创建的。 – wtaniguchi 2009-09-16 14:34:42

回答

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"); 
} 
+0

谢谢Omry.This是我也在想的东西,谢谢分享代码。 – Rajat 2009-09-16 15:23:11

3

不,没有 - 至少它是否落在int的范围内。 任何 int是一个有效的哈希码。特别是,对于任何int值x,散列值为new Integer(x) == x。然而,我认为存储对象的Java哈希代码通常不是一个好主意 - 如果哈希算法被指定并且永远不会改变,那么它是可以的 - 但是否则,当你要求麻烦时算法改变了,你的哈希值不再匹配。

1

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

1

有没有办法找到这样的。