Mishal Harish
Mishal Harish

Reputation: 103

Java program to generate a unique and random six alpha numeric code

I need to generate a reservation code of 6 alpha numeric characters, that is random and unique in java.

Tried using UUID.randomuuid().toString(), However the id is too long and the requirement demands that it should only be 6 characters.

What approaches are possible to achieve this?

Just to clarify, (Since this question is getting marked as duplicate). The other solutions I've found are simply generating random characters, which is not enough in this case. I need to reasonably ensure that a random code is not generated again.

Upvotes: 3

Views: 5771

Answers (6)

matt
matt

Reputation: 12347

Lets say your corpus is the collection of alpha numberic letters. a-zA-Z0-9.

char[] corpus = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789".toCharArray();

We can use SecureRandom to generate a seed, which will ask the OS for entropy, depending on the os. The trick here is to keep a uniform distribution, each byte has 255 values, but we only need around 62 so I will propose rejection sampling.

int generated = 0;
int desired=6;
char[] result= new char[desired];

while(generated<desired){
    byte[] ran = SecureRandom.getSeed(desired);
    for(byte b: ran){
       if(b>=0&&b<corpus.length){
           result[generated] = corpus[b];
           generated+=1;
           if(generated==desired) break;
       }
    }
}

Improvements could include, smarter wrapping of generated values.

When can we expect a repeat? Lets stick with the corpus of 62 and assume that the distribution is completely random. In that case we have the birthday problem. That gives us N = 62^6 possiblities. We want to find n where the chance of a repeat around 10%.

p(r)= 1 - N!/(N^n (N-n)!)

And using the approximation given in the wikipedia page.

n = sqrt(-ln(0.9)2N)

Which gives us about 109000 numbers for 10% chance. For a 0.1% chance it woul take about 10000 numbers.

Upvotes: 0

gaborsch
gaborsch

Reputation: 15758

You have 36 characters in the alphanumeric character set (0-9 digits + a-z letters). With 6 places you achieve 366 = 2.176.782.336 different options, that is slightly larger than 231.

Therefore you can use Unix time to create a unique ID. However, you must assure that no ID generated within the same second.

If you cannot guarantee that, you end up with a (synchronized) counter within your class. Also, if you want to survive a JVM restart, you should save the current value (e.g. to a database, file, etc. whatever options you have).

Upvotes: 2

Artjom B.
Artjom B.

Reputation: 61892

Despite its name, UUIDs are not unique. It's simply extremely unlikely to get a 128 bit collision. With 6 (less than 32 bit) it's very likely that you get a collision if you just hash stuff or generate a random string.

If the uniqueness constraint is necessary then you need to

  1. generate a random 6 character string
  2. Check if you generated that string before by querying your database
  3. If you generated it before, go back to 1

Another way would be to use a pseadorandom permutation (PRP) of size 32 bit. Block ciphers are modeled as PRP functions, but there aren't many that support 32 bit block sizes. Some are Speck by the NSA and the Hasty Pudding Cipher.

With a PRP you could for example take an already unique value like your database primary key and encrypt it with the block cipher. If the input is not bigger than 32 bit then the output will still be unique.

Then you would run Base62 (or at least Base 41) over the output and remove the padding characters to get a 6 character output.

Upvotes: 1

Strelok
Strelok

Reputation: 51441

Consider using the hashids library to generate salted hashes of integers (your database ids or other random integers which is probably better).

http://hashids.org/java/

Hashids hashids = new Hashids("this is my salt",6);
String id = hashids.encode(1, 2, 3);
long[] numbers = hashids.decode(id);

Upvotes: 3

lesnar
lesnar

Reputation: 2480

you can trying to make substring out of your generated UUID.

String uuid = UUID.randomUUID().toString();
System.out.println("uuid = " + uuid.substring(0,5);

Upvotes: -3

user155806
user155806

Reputation: 17

if you do a substring that value may not be unique

for more info please see following similar link Generating 8-character only UUIDs

Upvotes: 0

Related Questions