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.
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.
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 ?
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");
}