Question

After reading this answer: best way to pick a random subset from a collection?

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?

Was it helpful?

Solution

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.

OTHER TIPS

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.

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

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top