Seeding the random number generator in Javascript
No, it is not possible to seed Math.random()
, but it's fairly easy to write your own generator, or better yet, use an existing one.
Check out: this related question.
Also, see David Bau's blog for more information on seeding.
Seedable JavaScript random number generator
One option is http://davidbau.com/seedrandom which is a seedable RC4-based Math.random() drop-in replacement with nice properties.
Seedable Random number generator in JavaScript
This might help you, I just found it on the internet. It's apparently a replacement for Math.random()
http://davidbau.com/encode/seedrandom.js
Javascript random ordering with seed
jsFiddle Demo
You would need to seed a random value for each value in the array as far as I can tell. In that regards, you would probably want to do something like this:
for( var i = 0; i < length; i++ ){
seed.push(Math.random());
}
Where you are insuring that length
is the same length that the seed is for. This would be 4 for your simple example. Once that was done, you could pass the seed into your shuffle (or sort) function to ensure that the same results were obtained. The shuffle would need to use it in a loop as well
var randomIndex = parseInt(seed[i] * (len - i));
So here is what it all breaks down into
The seed function which will store the array of seeds
var seeder = function(){
var seed = [];
return {
set:function(length){
for( var i = 0; i < length; i++ ){
seed.push(Math.random());
}
return seed;
},
get: function(){
return seed;
},
clear: function(){
seed = [];
}
};
}
A pretty basic shuffle
function randomShuffle(ar,seed){
var numbers = [];
for( var a = 0, max = ar.length; a < max; a++){
numbers.push(a);
}
var shuffled = [];
for( var i = 0, len = ar.length; i < len; i++ ){
var r = parseInt(seed[i] * (len - i));
shuffled.push(ar[numbers[r]]);
numbers.splice(r,1);
}
return shuffled;
}
Being used
var arr = ["a", "b", "c", "d"];
var seed = seeder();
seed.set(arr.length);
console.log(randomShuffle(arr,seed.get()));
console.log(randomShuffle(arr,seed.get()));
console.log(randomShuffle(arr,seed.get()));
Predict the Seed of Javascript's Math.random
I looked through the Rhino source code to find out which pseudo-random function they use. Apparently they fall back to the Math.random
function defined in the Java standard library.
The documentation for Math.random
says:
Returns a double value with a positive sign, greater than or equal to 0.0 and less than 1.0. Returned values are chosen pseudorandomly with (approximately) uniform distribution from that range.
When this method is first called, it creates a single new pseudorandom-number generator, exactly as if by the expression
new java.util.Random
This new pseudorandom-number generator is used thereafter for all calls to this method and is used nowhere else.
This method is properly synchronized to allow correct use by more than one thread. However, if many threads need to generate pseudorandom numbers at a great rate, it may reduce contention for each thread to have its own pseudorandom-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 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.
So now we know for sure that the seed is the current time in milliseconds. Also, the documentation for the second constructor says:
Creates a new random number generator using a single long seed:
public Random(long seed) { setSeed(seed); }
Used by method next to hold the state of the pseudorandom number generator.
The documentation for the setSeed
method says:
Sets the seed of this random number generator using a single long seed. The general contract of setSeed is that it alters the state of this random number generator object so as to be in exactly the same state as if it had just been created with the argument seed as a seed. The method setSeed is implemented by class Random as follows:
synchronized public void setSeed(long seed) {
this.seed = (seed ^ 0x5DEECE66DL) & ((1L << 48) - 1);
haveNextNextGaussian = false;
}
The implementation of setSeed by class Random happens to use only 48 bits of the given seed. In general, however, an overriding method may use all 64 bits of the long argument as a seed value. Note: Although the seed value is an AtomicLong, this method must still be synchronized to ensure correct semantics of haveNextNextGaussian.
The actual method used to generate the random number is nextDouble
:
Returns the next pseudorandom, uniformly distributed double value between 0.0 and 1.0 from this random number generator's sequence.
The implementation of the nextDouble
function is as follows:
public double nextDouble() {
return (((long)next(26) << 27) + next(27))
/ (double)(1L << 53);
}
Clearly it depends on the next
function:
Generates the next pseudorandom number. Subclass should override this, as this 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));
}
That's the pseudo-random function you are looking for. As it's said in the documentation:
This is a linear congruential pseudorandom number generator, as defined by D. H. Lehmer and described by Donald E. Knuth in The Art of Computer Programming, Volume 2: Seminumerical Algorithms, section 3.2.1.
Note however that this is only the random number generator used by Rhino. Other implementations like Spidermonkey and V8 may have their own pseudo-random number generators.
Get a random integer between two given values that is seedable
Example from the library that you linked - seems to work (although I've edited it in order to cap it to the certain range).
const randGeneratorFrom = seed => { const generator = new Math.seedrandom(seed) return (min, max) => Math.floor(generator() * max) + min}
const now = new Date();const seed = [now.getUTCHours(), now.getUTCMinutes()].join(':')const rand = randGeneratorFrom(seed)
// results will be the same for the given hour:minuteconsole.info(seed)
console.info(rand(1, 25))console.info(rand(1, 25))console.info(rand(1, 25))console.info(rand(1, 25))
<script src="//cdnjs.cloudflare.com/ajax/libs/seedrandom/3.0.1/seedrandom.min.js"></script>
Seedable random number generator, actionscript
Here you go
http://gskinner.com/blog/archives/2008/01/source_code_see.html
Related Topics
Allow Google Chrome to Use Xmlhttprequest to Load a Url from a Local File
Differencebetween Parseint() and Number()
How to Check If Dst (Daylight Saving Time) Is in Effect, and If So, the Offset
Regular Expression to Get a String Between Parentheses in JavaScript
Detecting Arrow Key Presses in JavaScript
Function with Foreach Returns Undefined Even with Return Statement
Why Is My React Component Is Rendering Twice
Warn User Before Leaving Web Page with Unsaved Changes
Change Url Parameters and Specify Defaults Using JavaScript
How to Cancel an Http Fetch() Request
How to Download a File with Angular2 or Greater
When to Use Setattribute VS .Attribute= in JavaScript
In JavaScript, Why Is "0" Equal to False, But When Tested by 'If' It Is Not False by Itself