Link to home
Start Free TrialLog in
Avatar of wsyy
wsyy

asked on

How to generate a unique, specified lengthy number-alphabet string

Hi,

I would like to generate a 64 letter string based on a seed input; the input can be numbers, alphabet or combined.

The string should be unique and random.

Please advice!
Avatar of for_yan
for_yan
Flag of United States of America image

Avatar of wsyy
wsyy

ASKER

I should have mentioned that the random strings should be the same if the seed provided is the same.
I think this code from stackoverflow will generate you such string if you use seed in the Random constructor:

static final String AB = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
static Random rnd = new Random(seed);

String randomString( int len ) 
{
   StringBuilder sb = new StringBuilder( len );
   for( int i = 0; i < len; i++ ) 
      sb.append( AB.charAt( rnd.nextInt(AB.length()) ) );
   return sb.toString();
}

Open in new window

Avatar of wsyy

ASKER

unfortunately, the code doesn't work.

i think the reason is: rnd.nextInt(AB.length())
import java.util.Random;

public class GenerateUniqueCode {
	static final String AB = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
	static Random rnd = new Random();

	public static String randomString( int len ) 
	{
	   StringBuilder sb = new StringBuilder( len );
	   for( int i = 0; i < len; i++ ) 
	      sb.append( AB.charAt( rnd.nextInt(AB.length())));
	   return sb.toString();
	}
	
	public static void main(String[]args){
		System.out.println(randomString(64));
		System.out.println(randomString(64));
	}
	
}


outputs:
KITCS8W74WFOPA2PLYRYO9HA5JTGZ56PFODTDLACEGKCS53DTY943FEDXFJZRSZU
975Q2T0MS64SF1PGELRSJVL3VVRDRQB42IVPZATARA11VHCXP2AK5GP2GOLDHLXI

Open in new window

In what sense it does not work?
They are different - but you did not specify the seed in Random constructor
Besides, you need to create a new Random with the same seed to get the same sequence - otherwise it will continue and the sequence will be diffferenrt - you need to create a new Random(seed)with thhe same seed befoire beguinning to get each sequence
rnd.nextInt(AB.length()) generates int less then the AB.length - shoiukd be not a problem

Avatar of wsyy

ASKER

I replaced the original random generation statement with the following:
    static Random rnd = new Random(32859);

The outputs:
ISNQBT5ASFY73ZZ56I24FDNC7373K22PXXB6GXSQW8FI4FTLXKX2SEOG8HHDZBKA
3U1OP87CY83WNNWWRVN1B1STT9BXEVQDJ1D0Z7OH812TJR14YNMOD1Q3S7KD5171

Do I miss something?
Avatar of wsyy

ASKER

My code is below:
import java.util.Random;

public class GenerateUniqueCode {
	static final String AB = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
	static Random rnd = new Random(32859);

	static String randomString( int len ) 
	{
	   StringBuilder sb = new StringBuilder( len );
	   for( int i = 0; i < len; i++ ) 
	      sb.append( AB.charAt( rnd.nextInt(AB.length())));
	   return sb.toString();
	}
	
	public static void main(String[]args){
		System.out.println(randomString(64));
		System.out.println(randomString(64));
	}
}

outputs:
ISNQBT5ASFY73ZZ56I24FDNC7373K22PXXB6GXSQW8FI4FTLXKX2SEOG8HHDZBKA
3U1OP87CY83WNNWWRVN1B1STT9BXEVQDJ1D0Z7OH812TJR14YNMOD1Q3S7KD5171

Open in new window

To get both the same yoiu need bgfore generating second sequence to create new Random withe same seed
Avatar of wsyy

ASKER

Interestingly, I ran the code several times, and the results seem the same every time:

outputs:
ISNQBT5ASFY73ZZ56I24FDNC7373K22PXXB6GXSQW8FI4FTLXKX2SEOG8HHDZBKA
3U1OP87CY83WNNWWRVN1B1STT9BXEVQDJ1D0Z7OH812TJR14YNMOD1Q3S7KD5171

However, that is not what I want. Instead, I would like the two outputs are the same, say
outputs:
ISNQBT5ASFY73ZZ56I24FDNC7373K22PXXB6GXSQW8FI4FTLXKX2SEOG8HHDZBKA
ISNQBT5ASFY73ZZ56I24FDNC7373K22PXXB6GXSQW8FI4FTLXKX2SEOG8HHDZBKA
Avatar of wsyy

ASKER

Let me rephrase my needs:

1. I want to a 64-letter or number or combined, unique string;
2. For a certain seed input, number, letter or combined, the randomly generated string should remain the same whatever trials;
3. The randomly generated string based on 2. can be used as primary key of a database table.
That is all as expected
Do that:

In main:

Rnd = new Random(3269);
System.out$println(...)
Rnd = new Random(3269);
System.out.println(...y);
If you specify the same seed it starts the same sequence. If you don't create a new Random with the same seed in between, it continues to generate random numbers and that's why second 64 numbers will be differenet - because those arere next 64 numbers glfrom the random sequence. Yiou need toi create new random with the same seed to start the same sequence
ASKER CERTIFIED SOLUTION
Avatar of for_yan
for_yan
Flag of United States of America image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of wsyy

ASKER

Thanks for_yan!

May I ask a related question?

How to choose a seed random?

As to my question, I only have two inputs: (1) the string AB, (2) the length of 64.

Since I have so many, different ABs, I want to generate a seed random based on individual ABs, and use the seed as the third input together with (1) and (2) inputs for generating a 64-length string.

The other way is that I use a same seed for all the ABs, but I think this may cause problem as the number of ABs ascends to tens of billions.

What do you think?
I am not sure I understand what you mean. AB is all the time the same - it is just the array of those characters from which you slect your string and its length will be constant.

If you want every time to generate different sequence - then you should rather not provide any seed and call Random only once at the loadiung time of your applicatiion without paramneter.
When you call without parameter it takes as the seed number of current milliseconds so you may be guranteed that next time you start the program seed will in fact be different. Within one run oif the oprogram you rather not initialize random again so youi'll have all differnet sequences as the nunmbers will be actually gfrom one random sequence (so all 64 character sequences will be differnt). Of course if in thge process you somehwere call Random() withoiut oarameters you'll also get new sequence as number of milliseconds will be diferent, but it is unnecessary to Call it again.
 So with that you'll be guranteed toi have all tghe time differebt sequence.
In general, i prefer to generaate ids as consecutive numbers from Oracle sequence - usually works great for me
Avatar of CEHJ
>>3. The randomly generated string based on 2. can be used as primary key of a database table.

Not really possible as

a. although the probability is vanishingly small, duplicates could occur
b. it doesn't tally with your desire to deliberately produce a duplicate is the seed is the same

Why are you not using the auto-increment/sequence generation of a database to produce this?
If those considerations i mentioned are somehow not important in your case, there already is a UUID class in the API designed for this purpose. You can get your criteria satisfied with something like the below. There are also seeding variant of the ctor too which you could use
String uid64Chars = new StringBuilder().append(UUID.randomUUID().toString())
	    .append(UUID.randomUUID().toString()).toString().replaceAll("-", "");

Open in new window

Avatar of wsyy

ASKER

I think I got the solution:

I can use the hashcode of the string AB as the seed, which can be used to generate a random number.

The random number together with the length is then used to generate unique string.

Does this sound good?

I don't see where is your problem in general - just use new Random() one time without seed as it was in the original code - and I don't see any of your probkems that this arrangement would not solve

In general as was my opinion and you saw also CEHJ there is no reason why not to use databse means rto create your unique oid for each row - it usually works moe reliably