9

Is there any way that I can use a hashcode of a string in java, and recreate that string?

e.g. something like this:

String myNewstring = StringUtils.createFromHashCode("Hello World".hashCode());
if (!myNewstring.equals("Hello World"))
    System.out.println("Hmm, something went wrong: " + myNewstring);

I say this, because I must turn a string into an integer value, and reconstruct that string from that integer value.

14
  • why would u want that in first place? Commented Jun 13, 2011 at 18:29
  • @Srinivas Please read the entire question. Commented Jun 13, 2011 at 18:31
  • @adarshr and the long answer? I really don't care how large the code is, I just need to know how to do this. Commented Jun 13, 2011 at 18:32
  • 6
    The long answer is the same as the short answer -- just more words. Commented Jun 13, 2011 at 18:36
  • ... You haven't really answered the question. Why do you need to turn the string into an integer value and back? What are you going to do with the integer values? Commented Jun 13, 2011 at 18:38

6 Answers 6

6

This is impossible. The hash code for String is lossy; many String values will result in the same hash code. An integer has 32 bit positions and each position has two values. There's no way to map even just the 32-character strings (for instance) (each character having lots of possibilities) into 32 bits without collisions. They just won't fit.

If you want to use arbitrary precision arithmetic (say, BigInteger), then you can just take each character as an integer and concatenate them all together. Voilà.

Sign up to request clarification or add additional context in comments.

12 Comments

Then is there another method I could use? Some type of encoding?
@Richard, Base 10 is the encoding you are using.
@Richard What you need is encryption/decryption.
@Marcelo, any suggestions on what encryption to use?
I can't believe how senseless this idea of using encryption is. How on earth can anyone recover a possibly infinitely long message from a cipher text that is bounded to 32-bits?
|
4

No. Multiple Strings can have the same hash code. In theory you could create all the Strings that have have that hash code, but it would be near infinite.

3 Comments

Then is there another method I could use? Some type of encoding?
Or you could compress it. "Zip" the String using java.util.zip
Neither encryption nor compression will resolve his problem stated in the question. These are not magic terms to throw about to solve what is essentially a problem involving data loss.
2

Impossible I'm afraid. Think about it, a hashcode is a long value i.e. 8 bytes. A string maybe less than this but also could be much longer, you cannot squeeze a longer string into 8 bytes without losing something.

The Java hashcode algorithm sums every 8th byte if I remember correctly so you'd lose 7 out of 8 bytes. If your strings are all very short then you could encode them as an int or a long without losing anything.

Comments

1

For example, "1019744689" and "123926772" both have a hashcode of -1727003481. This proves that for any integer, you might get a different result (i.e. reversehashcode(hashcode(string)) != string).

Comments

0

Let's assume the string consists only of letters, digits and punctuation, so there are about 70 possible characters.

log_70{2^32} = 5.22...

This means for any given integer you will find a 5- or 6-character string with this as its hash code. So, retrieving "Hello World": impossible; but "Hello" might work if you're lucky.

2 Comments

Apparently, with very few exceptions, all English words map to a distinct number under Java's hashCode operation. So if you have the hash of a single word, you can step through a dictionary checking the hash codes, and have a very high chance of recovering the original word.
A very interesting find indeed. Alas, the question implies that an arbitrary string, or at least a sequence of multiple words, is to be stored.
0

You could do something like this:

char[] chars = "String here".toCharArray();
int[] ints = new int[chars.length];
for (int i = 0; i < chars.length; i++) {
    ints[i] = (int)chars[i];
}

Then:

char[] chars = new char[ints.length]
for (int i = 0; i < chars.length; i++) {
    chars[i] = (char)ints[i];
}
String final = new String(chars);

I have not actually tested this yet... It is just "concept" code.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.