2

I know it's one-way function but I want to convert hashcode back to limited set of string (using char between 32 to 126). Is there an efficient way to do this?

Saran
  • 443
  • 1
  • 7
  • 17
  • 8
    But there's an infinite number of such strings... – nneonneo Oct 07 '12 at 07:45
  • 1
    Maybe you can tell us **why** you would want to do so? – home Oct 07 '12 at 07:46
  • 1
    Actually, I only need one string from that hashcode. I want to make Minecraft seed shortener. – Saran Oct 07 '12 at 07:52
  • related: http://stackoverflow.com/questions/6334572/java-recreate-string-from-hashcode – Thilo Oct 07 '12 at 07:58
  • Why not use the same technique as a URL shortener? Just store the seeds in a database, and assign them a shorter string (or number). You may be able to construct a String for any given hashCode, but it is probably not the same as your original seed string. – Thilo Oct 07 '12 at 08:00
  • 2
    minecraft uses seed=givenStr.hashCode() to generate the world then it shows like -1030436604. I want to convert it back to String (not the same). – Saran Oct 07 '12 at 08:09

2 Answers2

4

It's not only feasible - it's actually pretty simple, given the definition for String.hashCode. You can just create a string of "base 31" characters with some arbitrary starting point to keep everything in the right range, subtracting an offset based on that starting point.

This isn't necessarily the shortest string with the given hash code, but 7 characters is pretty short :)

public class Test {

    public static void main(String[] args) {
        int hash = 100000;
        String sample = getStringForHashCode(hash);
        System.out.println(sample); // ASD^TYQ
        System.out.println(sample.hashCode()); // 100000
    }

    private static final int OFFSET = "AAAAAAA".hashCode();

    private static String getStringForHashCode(int hash) {
        hash -= OFFSET;
        // Treat it as an unsigned long, for simplicity.
        // This avoids having to worry about negative numbers anywhere.
        long longHash = (long) hash & 0xFFFFFFFFL;
        System.out.println(longHash);

        char[] c = new char[7];
        for (int i = 0; i < 7; i++)
        {
            c[6 - i] = (char) ('A' + (longHash % 31));
            longHash /= 31;
        }
        return new String(c);
    }
}
Jon Skeet
  • 1,421,763
  • 867
  • 9,128
  • 9,194
0

Actually, I only need one string from that hashcode. I want to make Minecraft seed shortener.

The simplest way to turn an int value into a short string is to use

String s = Integer.toString(n, 36); // uses base 36.
Peter Lawrey
  • 525,659
  • 79
  • 751
  • 1,130