├── LICENSE ├── aleaPRNG-1.1.min.js ├── README.md └── aleaPRNG-1.1.js /LICENSE: -------------------------------------------------------------------------------- 1 | BSD 3-Clause License 2 | 3 | Copyright (c) 2017-2020, W. "Mac" McMeans 4 | All rights reserved. 5 | 6 | Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 7 | 8 | * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 9 | 10 | * 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. 11 | 12 | * Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. 13 | 14 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 15 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 17 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 18 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 20 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 21 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 22 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 23 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 24 | -------------------------------------------------------------------------------- /aleaPRNG-1.1.min.js: -------------------------------------------------------------------------------- 1 | /*/////////////////////////////////////// 2 | aleaPRNG 1.1 3 | ///////////////////////////////////////// 4 | Copyright (c) 2017-2020, W. "Mac" McMeans 5 | LICENSE: BSD 3-Clause License 6 | https://github.com/macmcmeans/aleaPRNG/blob/master/aleaPRNG-1.1.min.js 7 | //////////////////////////////////////////*/ 8 | function aleaPRNG(){return function(n){"use strict";var r,t,e,o,a,u=new Uint32Array(3),i="";function c(n){var a=function(){var n=4022871197,r=function(r){r=r.toString();for(var t=0,e=r.length;t>>0,n=(o*=n)>>>0,n+=4294967296*(o-=n)}return 2.3283064365386963e-10*(n>>>0)};return r.version="Mash 0.9",r}();r=a(" "),t=a(" "),e=a(" "),o=1;for(var u=0;uarguments[1]&&(n=arguments[1],r=arguments[0]),f(n)&&f(r)?Math.floor(l()*(r-n+1))+n:l()*(r-n)+n},l.restart=function(){c(a)},l.seed=function(){c(Array.prototype.slice.call(arguments))},l.version=function(){return"aleaPRNG 1.1.0"},l.versions=function(){return"aleaPRNG 1.1.0, "+i},0===n.length&&(window.crypto.getRandomValues(u),n=[u[0],u[1],u[2]]),a=n,c(n),l}(Array.prototype.slice.call(arguments))} 9 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # 🔢 aleaPRNG [![Maintenance](https://img.shields.io/badge/Maintained%3F-yes-green.svg)](https://GitHub.com/Naereen/StrapDown.js/graphs/commit-activity) [![License](https://img.shields.io/badge/License-BSD%203--Clause-blue.svg)](https://opensource.org/licenses/BSD-3-Clause) 2 | Alea is a pseudo-random number generator (PRNG) created by Johannes Baagøe, released in 2010. It implements his variation on Marsaglia’s Multiply-with-carry theme, adapted to javascript’s quaint notion of numbers: the carries are exactly the integer parts of Numbers with exactly 32 bits of fractional part. 3 | 4 |
 
5 | Version 1.1
6 | Author: W. "Mac" McMeans
7 | Date: 29 APR 2020 8 |
 
9 | 10 |
 
11 | 12 |

13 | “Avoid the use of any generator that can’t be clearly, efficiently and portably implemented in a high-level language.”
~ S. Park, K. Miller & P. Stockmeyer
14 |

15 | 16 |
 
17 | 18 | ## Application: 19 | Use this to quickly generate random numbers with good statistical properties. NOTE: This generator is not cryptographically secure. If you need a secure generator then consider ISAAC for your application: a fast, long-period generator and discrete message cipher. 20 |
 
21 | 22 | 23 | ## Period: 24 | ~2116 25 |
 
26 | 27 | 28 | ## Example usage: 29 | 30 | ``` 31 | // return an instance of the generator initialized internally with Window.crypto 32 | > myRandomNumbers = aleaPRNG(); 33 | 34 | 35 | // return an instance of the generator initialized with specified seed 36 | > myRandomNumbers = aleaPRNG( 'my', '3', 'seeds' ); 37 | 38 | 39 | // return a 32-bit fraction in the range [0, 1] 40 | > myRandomNumbers(); --> 0.30802189325913787 41 | 42 | 43 | // advance the generator specified number of cycles 44 | > myRandomNumbers.prng( 4 ); 45 | 46 | 47 | // return an unsigned random integer in the range [0, 2^32] 48 | > myRandomNumbers.int32(); --> 704896377 49 | 50 | 51 | // return a 53-bit fraction in the range [0, 1] 52 | > myRandomNumbers.double(); --> 0.9397002613178349 53 | 54 | 55 | // return 32-bit range (inclusive) // 56 | // from -99 to 2.1275 57 | > myRandomNumbers.range( -99, 2.1275 ); --> -9.723206152322817 58 | 59 | // parameter order does not matter 60 | > myRandomNumbers.range( 100, -99 ); --> 43 61 | 62 | // from 0 to 12345 63 | > myRandomNumbers.range( 12345 ); --> 9929 64 | 65 | 66 | // reseed generator with a new value 67 | > myRandomNumbers.seed( 'this is a new seed' ); 68 | 69 | 70 | > myRandomNumbers(); --> 0.20963897299952805 71 | 72 | 73 | // restart generator (reverts back to first specified seed) 74 | > myRandomNumbers.restart(); 75 | 76 | 77 | // our first 32-bit fraction 78 | > myRandomNumbers(); --> 0.30802189325913787 79 | 80 | ``` 81 |
 
82 | 83 | 84 | ## REFS: 85 | https://github.com/nquinlan/better-random-numbers-for-javascript-mirror/blob/master/support/js/Alea.js 86 | 87 | [http://baagoe.com/en/RandomMusings/javascript/](https://archive.ph/fFiRk) 88 |
 
89 | 90 | 91 | ## Tested: 92 | Google Chrome on Win 10 (x64) 93 |
 
94 | 95 | ## Version notes: 96 | * 1.1 - 29 APR 2020 97 |
``update`` Refactor general logic 98 |
``update`` Remove dependency on Mash hash function 99 |
 
100 | 101 | * 1.0 - 23 JUL 2017 102 |
``release`` Initial release 103 |
 
104 | 105 | # License (BSD) 106 | Copyright (c) 2017-2020, W. "Mac" McMeans
107 | All rights reserved. 108 | 109 | Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 110 | 111 | 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 112 | 113 | 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. 114 | 115 | 3. Neither the name of copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. 116 | 117 | 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 HOLDER 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. 118 | -------------------------------------------------------------------------------- /aleaPRNG-1.1.js: -------------------------------------------------------------------------------- 1 | /*//////////////////////////////////////////////////////////////// 2 | aleaPRNG 1.1 3 | ////////////////////////////////////////////////////////////////// 4 | https://github.com/macmcmeans/aleaPRNG/blob/master/aleaPRNG-1.1.js 5 | ////////////////////////////////////////////////////////////////// 6 | Original work copyright © 2010 Johannes Baagøe, under MIT license 7 | This is a derivative work copyright (c) 2017-2020, W. Mac" McMeans, under BSD license. 8 | Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 9 | 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 10 | 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. 11 | 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. 12 | 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 HOLDER 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. 13 | ////////////////////////////////////////////////////////////////*/ 14 | function aleaPRNG() { 15 | return( function( args ) { 16 | "use strict"; 17 | 18 | const version = 'aleaPRNG 1.1.0'; 19 | 20 | var s0 21 | , s1 22 | , s2 23 | , c 24 | , uinta = new Uint32Array( 3 ) 25 | , initialArgs 26 | , mashver = '' 27 | ; 28 | 29 | /* private: initializes generator with specified seed */ 30 | function _initState( _internalSeed ) { 31 | var mash = Mash(); 32 | 33 | // internal state of generator 34 | s0 = mash( ' ' ); 35 | s1 = mash( ' ' ); 36 | s2 = mash( ' ' ); 37 | 38 | c = 1; 39 | 40 | for( var i = 0; i < _internalSeed.length; i++ ) { 41 | s0 -= mash( _internalSeed[ i ] ); 42 | if( s0 < 0 ) { s0 += 1; } 43 | 44 | s1 -= mash( _internalSeed[ i ] ); 45 | if( s1 < 0 ) { s1 += 1; } 46 | 47 | s2 -= mash( _internalSeed[ i ] ); 48 | if( s2 < 0 ) { s2 += 1; } 49 | } 50 | 51 | mashver = mash.version; 52 | 53 | mash = null; 54 | }; 55 | 56 | /* private: dependent string hash function */ 57 | function Mash() { 58 | var n = 4022871197; // 0xefc8249d 59 | 60 | var mash = function( data ) { 61 | data = data.toString(); 62 | 63 | // cache the length 64 | for( var i = 0, l = data.length; i < l; i++ ) { 65 | n += data.charCodeAt( i ); 66 | 67 | var h = 0.02519603282416938 * n; 68 | 69 | n = h >>> 0; 70 | h -= n; 71 | h *= n; 72 | n = h >>> 0; 73 | h -= n; 74 | n += h * 4294967296; // 0x100000000 2^32 75 | } 76 | return ( n >>> 0 ) * 2.3283064365386963e-10; // 2^-32 77 | }; 78 | 79 | mash.version = 'Mash 0.9'; 80 | return mash; 81 | }; 82 | 83 | 84 | /* private: check if number is integer */ 85 | function _isInteger( _int ) { 86 | return parseInt( _int, 10 ) === _int; 87 | }; 88 | 89 | /* public: return a 32-bit fraction in the range [0, 1] 90 | This is the main function returned when aleaPRNG is instantiated 91 | */ 92 | var random = function() { 93 | var t = 2091639 * s0 + c * 2.3283064365386963e-10; // 2^-32 94 | 95 | s0 = s1; 96 | s1 = s2; 97 | 98 | return s2 = t - ( c = t | 0 ); 99 | }; 100 | 101 | /* public: return a 53-bit fraction in the range [0, 1] */ 102 | random.fract53 = function() { 103 | return random() + ( random() * 0x200000 | 0 ) * 1.1102230246251565e-16; // 2^-53 104 | }; 105 | 106 | /* public: return an unsigned integer in the range [0, 2^32] */ 107 | random.int32 = function() { 108 | return random() * 0x100000000; // 2^32 109 | }; 110 | 111 | /* public: advance the generator the specified amount of cycles */ 112 | random.cycle = function( _run ) { 113 | _run = typeof _run === 'undefined' ? 1 : +_run; 114 | if( _run < 1 ) { _run = 1; } 115 | for( var i = 0; i < _run; i++ ) { random(); } 116 | }; 117 | 118 | /* public: return inclusive range */ 119 | random.range = function() { 120 | var loBound 121 | , hiBound 122 | ; 123 | 124 | if( arguments.length === 1 ) { 125 | loBound = 0; 126 | hiBound = arguments[ 0 ]; 127 | 128 | } else { 129 | loBound = arguments[ 0 ]; 130 | hiBound = arguments[ 1 ]; 131 | } 132 | 133 | if( arguments[ 0 ] > arguments[ 1 ] ) { 134 | loBound = arguments[ 1 ]; 135 | hiBound = arguments[ 0 ]; 136 | } 137 | 138 | // return integer 139 | if( _isInteger( loBound ) && _isInteger( hiBound ) ) { 140 | return Math.floor( random() * ( hiBound - loBound + 1 ) ) + loBound; 141 | 142 | // return float 143 | } else { 144 | return random() * ( hiBound - loBound ) + loBound; 145 | } 146 | }; 147 | 148 | /* public: initialize generator with the seed values used upon instantiation */ 149 | random.restart = function() { 150 | _initState( initialArgs ); 151 | }; 152 | 153 | /* public: seeding function */ 154 | random.seed = function() { 155 | _initState( Array.prototype.slice.call( arguments ) ); 156 | }; 157 | 158 | /* public: show the version of the RNG */ 159 | random.version = function() { 160 | return version; 161 | }; 162 | 163 | /* public: show the version of the RNG and the Mash string hasher */ 164 | random.versions = function() { 165 | return version + ', ' + mashver; 166 | }; 167 | 168 | // when no seed is specified, create a random one from Windows Crypto (Monte Carlo application) 169 | if( args.length === 0 ) { 170 | window.crypto.getRandomValues( uinta ); 171 | args = [ uinta[ 0 ], uinta[ 1 ], uinta[ 2 ] ]; 172 | }; 173 | 174 | // store the seed used when the RNG was instantiated, if any 175 | initialArgs = args; 176 | 177 | // initialize the RNG 178 | _initState( args ); 179 | 180 | return random; 181 | 182 | })( Array.prototype.slice.call( arguments ) ); 183 | }; 184 | --------------------------------------------------------------------------------