Created
September 9, 2015 02:20
-
-
Save satori99/6f8a97161133d3d9f4ea to your computer and use it in GitHub Desktop.
Replaces Math.random() with a seedable pseudo-random number function
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
* A seedable (deterministic) psuedo-random number generator | |
* | |
* This script replaces native Math.random() with a deterministic psuedo-random | |
* number generator. It also adds a static method to reset the prng stream and | |
* optionally set a new seed string. | |
* | |
* @function random | |
* @memberof Math | |
* @description Generates a deterministic psuedo-random number between zero and one | |
* @returns {Number} psuedo-random number between zero and one | |
* | |
* @function reset | |
* @static | |
* @memberof Math.random | |
* @description Resets the prng stream, optionally with a new seed | |
* @param {String} [seed] - Optional seed text | |
* @returns undefined | |
* | |
* @property {String} seed - Current seed string | |
* @static | |
* @memberof Math.random | |
* @readonly | |
* | |
* @function native | |
* @static | |
* @memberof Math.random | |
* @description Native random function | |
* @returns {Number} random number between zero and one | |
*/ | |
(function() { | |
'use strict'; | |
var _native = Math.random; | |
var _seed = _native().toString( 36 ).slice( 2 ); | |
var _state = new Uint8Array( 256 ); | |
var _i = 0; | |
var _j = 0; | |
var _t = 0; | |
function swap ( i, j ) { | |
_t = _state[ i ]; | |
_state[ i ] = _state[ j ]; | |
_state[ j ] = _t; | |
} | |
function next () { | |
_i = ( _i + 1 ) % 256; | |
_j = ( _j + _state[ _i ] ) % 256; | |
swap( _i, _j ); | |
return _state[ ( _state[ _i ] + _state[ _j ] ) % 256 ]; | |
} | |
Object.defineProperty( Math, 'random', { | |
value: function () { | |
return Object.defineProperties( | |
function random () { | |
var r = next(); | |
r = r * 256 + next(); | |
r = r * 256 + next(); | |
r = r * 256 + next(); | |
r = r * 256 + next(); | |
r = r * 256 + next(); | |
r = r * 256 + next(); | |
return r / 0x100000000000004; | |
}, { | |
reset: { | |
value: function ( seed ) { | |
_seed = seed ? String( seed ).trim().slice( 0, 256 ) : _seed; | |
_state.set( Array.apply( 0, Array( 256 ) ).map( function ( x, y ) { return y; } ) ); | |
for ( var i = 0, j = 0; i < 256; i ++ ) { | |
swap( i, j = ( j + _state[ i ] + _seed[ i % _seed.length ].charCodeAt( 0 ) ) % 256 ); | |
} | |
_i = _j = 0; | |
}, | |
enumerable: true | |
}, | |
seed: { get: function () { return _seed; }, enumerable: true }, | |
native: { value: _native, enumerable: true } | |
} ); | |
}() | |
} ); | |
Math.random.reset(); | |
}()); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment