java - Secure non-repeating Random alphanumeric URL slug -


i'm able achieve non-repeating random alphanumeric url slug part base58, this,

private static final char[] base58_chars = "123456789abcdefghjklmnpqrstuvwxyzabcdefghijkmnopqrstuvwxyz".tochararray(); private static final int length = base58_chars.length; public static string genslug(long priimarykeyid) {     char[] buffer = new char[20];     int index = 0;     {         int = (int) (priimarykeyid % length);         buffer[index++] = base58_chars[i];         priimarykeyid = priimarykeyid / length;     } while (priimarykeyid > 0);     return new string(buffer, 0, index); } 

but how achieve secure-randomness it?

if

hashing.sha256().hashstring(genslug(priimarykeyid), standardcharsets.utf_8).tostring(); 

the slug becomes 64 characters , that's long (expecting same length genslug, between 1 , 12 chars long)..

you truncate output of hash function , still appear random, possibility of hash collision rise. since constraint maximum output of 12 characters, means have truncate hash output 70 bits (12/8 * log(256)/log(58)). due birthday paradox, collision after 270/2 such hashes.

since need guaranteed uniqueness, can use pseudo-random permutation (prp) transform priimarykeyid random token. block cipher such prp. since maximum size of block size 70, can safely use triple des use case. has block size of 64 bit size of long.

example (not thoroughly tested):

private static final char[] base58_chars = "123456789abcdefghjklmnpqrstuvwxyzabcdefghijkmnopqrstuvwxyz".tochararray(); private static final int length = base58_chars.length; private static final biginteger length_bi = biginteger.valueof(length);  // todo: change key random! private static final byte[] key = new byte {1,2,3,4,5,6,7,8,1,2,3,4,5,6,7,8,1,2,3,4,5,6,7,8};  public static string genslug(long priimarykeyid) {     bytebuffer bb = bytebuffer.allocate(8);     bb.putlong(priimarykeyid);      cipher cipher = cipher.getinstance("desede/ecb/nopadding");     cipher.init(cipher.encrypt_mode, new secretkeyspec(key, "desede"));     byte[] encrypted = cipher.dofinal(bb.array());     biginteger bi = new biginteger(1, encrypted);      char[] buffer = new char[20];     int index = 0;     {         biginteger = bi.mod(length_bi);         buffer[index++] = base58_chars[i.intvalue()];         bi = bi.divide(length_bi);     } while (bi.compareto(biginteger.zero) == 1);     return new string(buffer, 0, index); } 

the main thing need keep key safe.


Comments

Popular posts from this blog

ubuntu - PHP script to find files of certain extensions in a directory, returns populated array when run in browser, but empty array when run from terminal -

php - How can i create a user dashboard -

javascript - How to detect toggling of the fullscreen-toolbar in jQuery Mobile? -