views:

339

answers:

3

After reading this answer: http://stackoverflow.com/questions/136474/best-way-to-pick-a-random-subset-from-a-collection#136513

It got me wondering, how does one pick a random seed in Java?

And don't say use System.currentTimeMillis() or System.nanoTime(). Read the article to see why not.

That's a hard question, but let me make it harder. Let's say you need to generate a random seed without connecting to the internet, without using user input (IE, there's no gui), and it has to be cross platform (therefore no JNI to access hardware).

Is there some JVM variables we can monitor as a source of our randomness?

Can this be done? Or is it impossible?

+4  A: 

Take a look at Uncommons Maths (full disclosure: I wrote it). It should solve most of the problems you'll ever have with random numbers in Java.

Even, if you don't use it you should be able to get some ideas from the various SeedGenerator implementations it provides. Basically, it defaults to using /dev/random. If that doesn't exist (e.g. Windows) it either tries to download data from random.org or it uses SecureRandom.generateSeed.

I think SecureRandom.generateSeed is the best that you can do without relying on anything platform specific or on the Internet.

Dan Dyer
Oh wow, you have a CombinationGenerator too!I wrote one just like that a few days ago...
Pyrolistical
I added Uncommons Maths to my other question:http://stackoverflow.com/questions/130095/most-useful-free-java-libraries#136905
Pyrolistical
I hope you use https to connect to random.org.
Steve Jessop
A: 

Combine System.currentTimeMillis() with a global counter that you increment every time you generate the seed. Use AtomicLong for the counter so you can increment with efficiency and thread safety.

"Combine" doesn't mean "add" or "xor" because it's too easy to get duplicates. Instead, hash. You could get complicated and stuff the long and the counter into e.g. 16 bytes and MD5 it, but I would probably use a 64-bit version of the Adler CRC or some other 64-bit CRC.

Jason Cohen
A: 

Um, that article says that 32-bit seeds are bad, but 64-bit seeds are good. System.currentTimeMillis() is a 64-bit seed.

james
The current currentTimeMillis() in hex is:0x00 00 01 1C 9F B4 CF 78Does that look like a very good 64-bit number? Sure you can hash it to a better 64-bit number, but your source is still less than 64-bits.In my application, I actually need over 700 bits for the seed.
Pyrolistical