114 lines
4.3 KiB
JavaScript
114 lines
4.3 KiB
JavaScript
// this program is a JavaScript version of Mersenne Twister, with concealment and encapsulation in class,
|
|
// an almost straight conversion from the original program, mt19937ar.c,
|
|
// translated by y. okada on July 17, 2006.
|
|
|
|
// Changes by Jesse Ruderman:
|
|
// * Use intish/int32 rather than uint32 for intermediate calculations
|
|
// (see https://bugzilla.mozilla.org/show_bug.cgi?id=883748#c1)
|
|
// * Added functions for exporting/importing the entire PRNG state
|
|
// * Removed parts not needed for fuzzing
|
|
|
|
// in this program, procedure descriptions and comments of original source code were not removed.
|
|
// lines commented with //c// were originally descriptions of c procedure. and a few following lines are appropriate JavaScript descriptions.
|
|
// lines commented with /* and */ are original comments.
|
|
// lines commented with // are additional comments in this JavaScript version.
|
|
// before using this version, create at least one instance of MersenneTwister19937 class, and initialize the each state, given below in c comments, of all the instances.
|
|
|
|
/*
|
|
A C-program for MT19937, with initialization improved 2002/1/26.
|
|
Coded by Takuji Nishimura and Makoto Matsumoto.
|
|
|
|
Copyright (C) 1997 - 2002, Makoto Matsumoto and Takuji Nishimura,
|
|
All rights reserved.
|
|
|
|
Redistribution and use in source and binary forms, with or without
|
|
modification, are permitted provided that the following conditions
|
|
are met:
|
|
|
|
1. Redistributions of source code must retain the above copyright
|
|
notice, this list of conditions and the following disclaimer.
|
|
|
|
2. Redistributions in binary form must reproduce the above copyright
|
|
notice, this list of conditions and the following disclaimer in the
|
|
documentation and/or other materials provided with the distribution.
|
|
|
|
3. The names of its contributors may not be used to endorse or promote
|
|
products derived from this software without specific prior written
|
|
permission.
|
|
|
|
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
|
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
|
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
|
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
|
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
|
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
|
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
|
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
|
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
|
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
|
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
|
|
|
|
Any feedback is very welcome.
|
|
http://www.math.sci.hiroshima-u.ac.jp/~m-mat/MT/emt.html
|
|
email: m-mat @ math.sci.hiroshima-u.ac.jp (remove space)
|
|
*/
|
|
|
|
|
|
function MersenneTwister19937()
|
|
{
|
|
const N = 624;
|
|
const M = 397;
|
|
const MAG01 = new Int32Array([0, 0x9908b0df]);
|
|
|
|
var mt = new Int32Array(N); /* the array for the state vector */
|
|
var mti = 625;
|
|
|
|
this.seed = function (s) {
|
|
mt[0] = s | 0;
|
|
for (mti=1; mti<N; mti++) {
|
|
mt[mti] = Math.imul(1812433253, mt[mti-1] ^ (mt[mti-1] >>> 30)) + mti;
|
|
}
|
|
};
|
|
|
|
this.export_state = function() { return [mt, mti]; };
|
|
this.import_state = function(s) { mt = s[0]; mti = s[1]; };
|
|
this.export_mta = function() { return mt; };
|
|
this.import_mta = function(_mta) { mt = _mta; };
|
|
this.export_mti = function() { return mti; };
|
|
this.import_mti = function(_mti) { mti = _mti; };
|
|
|
|
function mag01(y)
|
|
{
|
|
return MAG01[y & 0x1];
|
|
}
|
|
|
|
this.int32 = function () {
|
|
var y;
|
|
var kk;
|
|
|
|
if (mti >= N) { /* generate N words at one time */
|
|
for (kk=0;kk<N-M;kk++) {
|
|
y = ((mt[kk]&0x80000000)|(mt[kk+1]&0x7fffffff));
|
|
mt[kk] = (mt[kk+M] ^ (y >>> 1) ^ mag01(y));
|
|
}
|
|
for (;kk<N-1;kk++) {
|
|
y = ((mt[kk]&0x80000000)|(mt[kk+1]&0x7fffffff));
|
|
mt[kk] = (mt[kk+(M-N)] ^ (y >>> 1) ^ mag01(y));
|
|
}
|
|
y = ((mt[N-1]&0x80000000)|(mt[0]&0x7fffffff));
|
|
mt[N-1] = (mt[M-1] ^ (y >>> 1) ^ mag01(y));
|
|
mti = 0;
|
|
}
|
|
|
|
y = mt[mti++];
|
|
|
|
/* Tempering */
|
|
y = y ^ (y >>> 11);
|
|
y = y ^ ((y << 7) & 0x9d2c5680);
|
|
y = y ^ ((y << 15) & 0xefc60000);
|
|
y = y ^ (y >>> 18);
|
|
|
|
return y;
|
|
};
|
|
}
|