2009-09-16 99 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

有沒有辦法找到這樣的。