Reputation: 33
from my research everyone seems to say that java random uses the system time in milliseconds as its default seed when one is not specified. So, following this if we have the system time at the moment a random number is generated we should be able to know what seed generates that number. So,
(new Random()).nextLong;
long time = System.currentTimeMillis();
(new Random(time)).nextLong
should produce two identical numbers as the seed is the same, right? It doesn't so either it doesn't use TimeMillis as the seed or I'm doing something else wrong.
Thanks so much for any help, I've searched for hours but can't seem to find a consistent answer. I just want to know exactly how it finds a seed when one is not specified. My thinking is maybe it does use the system time but it multiplies it etc before coming to a final seed.
Thanks again :)
Upvotes: 3
Views: 2183
Reputation: 111219
Java used to use the system time as the default seed, up to 1.4.2. In 1.5 this "bug" was fixed. Compare the 1.4.2 API specification:
Creates a new random number generator. Its seed is initialized to a value based on the current time:
public Random() { this(System.currentTimeMillis()); }
Two Random objects created within the same millisecond will have the same sequence of random numbers.
With the 1.5 API specification:
Creates a new random number generator. This constructor sets the seed of the random number generator to a value very likely to be distinct from any other invocation of this constructor.
The current implementation in OpenJDK uses a static AtomicLong
which is updated every time you create a new Random
instance without a seed. If you don't have the source code locally, you can find it in the source code on github:
public Random() {
this(seedUniquifier() ^ System.nanoTime());
}
private static long seedUniquifier() {
// L'Ecuyer, "Tables of Linear Congruential Generators of
// Different Sizes and Good Lattice Structure", 1999
for (;;) {
long current = seedUniquifier.get();
long next = current * 1181783497276652981L;
if (seedUniquifier.compareAndSet(current, next))
return next;
}
}
private static final AtomicLong seedUniquifier
= new AtomicLong(8682522807148012L);
Upvotes: 8