Convert Java hash to random string

I am trying to develop a reduction function for use in a rainbow generator.

The basic principle of the reduction function is that it takes a hash, performs some calculations, and returns a string of a certain length.

I am currently using SHA1 hashes, and I need to return a string of length three. I need a string that should be composed on any three random characters from:

abcdefghijklmnopqrstuvwxyz0123456789 

The main problem that I am facing is that any writing function that I write always returns the lines already created. And a good cut function will only return duplicate rows.

Can anyone suggest any ideas on how to achieve this? Or any suggestions about string hash manipulation in general would be great.

Thanks in advance

Josh

+6
source share
2 answers

Application of the KISS principle:

  • SHA is just a string
  • JDK hash code for String "random enough"
  • Integer can display in any database

This single line of code does this:

 public static String shortHash(String sha) { return Integer.toString(sha.hashCode() & 0x7FFFFFFF, 36).substring(0, 3); } 

Note. & 0x7FFFFFFF is the zero bit of the sign (hash codes can be negative numbers that would otherwise be displayed using the minus sign).

Edit - Guarantee hash length

My initial decision was naive - it did not address the case where the int hash is less than 100 (base 36) - this means that it prints less than 3 characters. This code fixes this while retaining the value of "random". It also avoids calling substring() , so performance should be better.

 static int min = Integer.parseInt("100", 36); static int range = Integer.parseInt("zzz", 36) - min; public static String shortHash(String sha) { return Integer.toString(min + (sha.hashCode() & 0x7FFFFFFF) % range, 36); } 

This code ensures that the final hash has 3 characters, forcing it to be between 100 and zzz - the lowest and highest tag <-> w980> in base 36, while still making it "random."

+4
source

So it looks like you have 20 digits of base 255 (SHA1 hash length) that you need to map to three digits of base 36. I would just make BigInteger from the hash bytes, module 36 ^ 3 and return the string to base 36.

 public static final BigInteger N36POW3 = new BigInteger(""+36*36*36)); public static String threeDigitBase36(byte[] bs) { return new BigInteger(bs).mod(N36POW3).toString(36); } // ... threeDigitBase36(sha1("foo")); // => "96b" threeDigitBase36(sha1("bar")); // => "y4t" threeDigitBase36(sha1("bas")); // => "p55" threeDigitBase36(sha1("zip")); // => "ej8" 

Of course, there will be collisions, as when comparing any space with a smaller one, but entropy should be better than something even stronger than the above solution.

+6
source

Source: https://habr.com/ru/post/908850/


All Articles