tags:

views:

217

answers:

4

In our application we generate hashcode from a java object and store it in the database at some level. Now my questions is if somebody generates a number by hand, is there a way i can find out whether it is a valid hashcode created by the JVM from an Object and not manually created by hand.

+3  A: 

No, there isn't - at least if it falls in the range of int. Any int is a valid hashcode. In particular, for any int value x, the hash of new Integer(x) == x.

I would say, however, that storing the Java hash codes of objects generally isn't a good idea - it's okay if the hashing algorithm is specified and will never, ever change - but otherwise you're asking for trouble when the algorithm changes and none of your hashes match any more.

Jon Skeet
+1  A: 

No. The basic hashCode() operation is at liberty to return any int, provided it's consistent. I think the real question is what are you trying to do ?

Brian Agnew
+3  A: 

if you want to keep a 'signature' of your object in the database, use a different function. hashCode is not designed to be hard to guess or reverse engineer.

since you used hashCode, I assume that you do not care about having the same F(X) = F(Y) where X and Y are different object.

if this is indeed the case, consider using an hashing function, maybe plus some "secret" salt. for example:

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");
}
Omry
Thanks Omry.This is something that i was also thinking about, thanks for sharing the code.
Rajat
+1  A: 

there is no way to find this as such.

Aadith