Predict Javascript seed Math.random

Okay, so I'm doing some research on how random numbers are generated using the Math.random method. So far I have learned that it starts with a β€œrandom” seed, and this seed connects to some complicated equation to create a random number. If the seed is always the same, will the result always be the same?

I heard that seeds for Math.random are being generated in the current time, is that right? They should use the current time up to a mile-second or something else, because if you did not, you will get the same result.

What is a seed? Is it a time like β€œ10:45” or a time and date, like β€œ10:45 11/8/12” or some combination?

How can I find a seed, so I can predict the way out?

I want to be able to connect this:

alert(Math.floor((Math.random()*10)+1)); 

into my url string and you can predict the result. Is it possible?

+8
javascript random seed
source share
4 answers

I looked at the Rhino source code to find out which pseudo-random function they use. Apparently they Math.random to the Math.random function defined in the standard Java library .

The documentation for Math.random states:

Returns a double value with a positive sign greater than or equal to 0.0 and less than 1.0. Returned values ​​are selected pseudo-randomly with (approximately) uniform distribution from this range.

When this method is first called, it creates one new pseudo-random number generator, just as if the expression

 new java.util.Random 

This new pseudo-random number generator is used for all calls to this method and is not used anywhere else.

This method is correctly synchronized to ensure proper use by multiple threads. However, if many streams need to generate pseudo-random numbers at high speed, this can reduce competition for each stream to have its own pseudo-random number generator.

So, I checked the documentation for java.util.Random and found this (for the default constructor):

Creates a new random number generator. Its seed is initialized with a value based on the current time:

 public Random() { this(System.currentTimeMillis()); } 

Two random objects created within one millisecond will have the same sequence of random numbers.

So, now we know for sure that the seed is the current time in milliseconds. In addition, the documentation for the second constructor says:

Creates a new random number generator using one long seed:

 public Random(long seed) { setSeed(seed); } 

Used by the method next to the state of the pseudo random number generator.

The documentation for the setSeed method says:

Sets the seed of this random number generator using one long seed. The general setSeed contract is that it changes the state of this random number generator object to be in exactly the same state as if it had just been created with the argument seed as the seed. The setSeed method is implemented by the Random class as follows:

 synchronized public void setSeed(long seed) { this.seed = (seed ^ 0x5DEECE66DL) & ((1L << 48) - 1); haveNextNextGaussian = false; } 

The random setSeed implementation uses only 48 bits of a given seed. In general, however, an overriding method can use all 64 bits of a long argument as an initial value. Note. Although the initial value is AtomicLong, this method must still be synchronized to ensure proper hasNextNextGaussian semantics.

actual method used to generate the nextDouble random number:

Returns the next pseudorandom uniformly distributed double value between 0.0 and 1.0 from this sequence of random number generators.

The implementation of the nextDouble function is as follows:

 public double nextDouble() { return (((long)next(26) << 27) + next(27)) / (double)(1L << 53); } 

Obviously, it depends on the next function:

Creates the following pseudo-random number. The subclass should override this as it is used by all other methods.

The implementation of the next function is as follows:

 synchronized protected int next(int bits) { seed = (seed * 0x5DEECE66DL + 0xBL) & ((1L << 48) - 1); return (int)(seed >>> (48 - bits)); } 

This is the pseudo-random function you are looking for. As the documentation says:

This is a linear congruent pseudo-random number generator, as defined by D. Kh. Lemer and described by Donald E. Knut in β€œThe Art of Programming,” Volume 2: β€œSeven-Dimensional Algorithms,” section 3.2.1.

Please note that this is only a random number generator used by Rhino. Other implementations, such as Spidermonkey and V8, may have their own pseudo random number generators.

+14
source share

It is likely that there is more seed than a millisecond count, because you can call Math.random () many times in the same millisecond, and each time it will return a different value.

 for (var i = 0; i < 3; i++) { console.log(Math.random(), (new Date()).getTime()); }; 

My conclusion:

 0.0617244818713516 1352433709108 0.8024995378218591 1352433709108 0.2409922298975289 1352433709108 

If I implemented it, I could make an initial seed based on a millisecond count, and then add 1 each time it is called so that you don't get the same initial value twice.

Here's a 100% accurate way to predict the output from Math.random() :

 Math.random = function () { return .5; }; 

Now Math.random() will always return .5 .

+6
source share

Seed is a numeric value, so I assume that it will be what you get if you call Date.now() (or new Date().getTime() for old browsers).

However, I am not sure when this seed will be taken, or if the seed is isolated from the current page or will be common to the entire browser process. Predicting random numbers must be very difficult or impossible that they are all random.

0
source share

No, you cannot predict the seed, but you can pre-generate enough numbers to accurately copy the power.

In any case, starting with reading the wiki page on the RNG - http://en.wikipedia.org/wiki/Random_number_generation , look at the practical implementations of PRNG.

0
source share

All Articles