1// seedrandom.js version 2.0. 2// Author: David Bau 4/2/2011 3// 4// Defines a method Math.seedrandom() that, when called, substitutes 5// an explicitly seeded RC4-based algorithm for Math.random(). Also 6// supports automatic seeding from local or network sources of entropy. 7// 8// Usage: 9// 10// <script src=http://davidbau.com/encode/seedrandom-min.js></script> 11// 12// Math.seedrandom('yipee'); Sets Math.random to a function that is 13// initialized using the given explicit seed. 14// 15// Math.seedrandom(); Sets Math.random to a function that is 16// seeded using the current time, dom state, 17// and other accumulated local entropy. 18// The generated seed string is returned. 19// 20// Math.seedrandom('yowza', true); 21// Seeds using the given explicit seed mixed 22// together with accumulated entropy. 23// 24// <script src="http://bit.ly/srandom-512"></script> 25// Seeds using physical random bits downloaded 26// from random.org. 27// 28// <script src="https://jsonlib.appspot.com/urandom?callback=Math.seedrandom"> 29// </script> Seeds using urandom bits from call.jsonlib.com, 30// which is faster than random.org. 31// 32// Examples: 33// 34// Math.seedrandom("hello"); // Use "hello" as the seed. 35// document.write(Math.random()); // Always 0.5463663768140734 36// document.write(Math.random()); // Always 0.43973793770592234 37// var rng1 = Math.random; // Remember the current prng. 38// 39// var autoseed = Math.seedrandom(); // New prng with an automatic seed. 40// document.write(Math.random()); // Pretty much unpredictable. 41// 42// Math.random = rng1; // Continue "hello" prng sequence. 43// document.write(Math.random()); // Always 0.554769432473455 44// 45// Math.seedrandom(autoseed); // Restart at the previous seed. 46// document.write(Math.random()); // Repeat the 'unpredictable' value. 47// 48// Notes: 49// 50// Each time seedrandom('arg') is called, entropy from the passed seed 51// is accumulated in a pool to help generate future seeds for the 52// zero-argument form of Math.seedrandom, so entropy can be injected over 53// time by calling seedrandom with explicit data repeatedly. 54// 55// On speed - This javascript implementation of Math.random() is about 56// 3-10x slower than the built-in Math.random() because it is not native 57// code, but this is typically fast enough anyway. Seeding is more expensive, 58// especially if you use auto-seeding. Some details (timings on Chrome 4): 59// 60// Our Math.random() - avg less than 0.002 milliseconds per call 61// seedrandom('explicit') - avg less than 0.5 milliseconds per call 62// seedrandom('explicit', true) - avg less than 2 milliseconds per call 63// seedrandom() - avg about 38 milliseconds per call 64// 65// LICENSE (BSD): 66// 67// Copyright 2010 David Bau, all rights reserved. 68// 69// Redistribution and use in source and binary forms, with or without 70// modification, are permitted provided that the following conditions are met: 71// 72// 1. Redistributions of source code must retain the above copyright 73// notice, this list of conditions and the following disclaimer. 74// 75// 2. Redistributions in binary form must reproduce the above copyright 76// notice, this list of conditions and the following disclaimer in the 77// documentation and/or other materials provided with the distribution. 78// 79// 3. Neither the name of this module nor the names of its contributors may 80// be used to endorse or promote products derived from this software 81// without specific prior written permission. 82// 83// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 84// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 85// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 86// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 87// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
vendor: 4,424 bytes, lines 88-223
88// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 89// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 90// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 91// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 92// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 93// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 94// 95/** 96 * All code is in an anonymous closure to keep the global namespace clean. 97 * 98 * @param {number=} overflow 99 * @param {number=} startdenom 100 */ 101(function (pool, math, width, chunks, significance, overflow, startdenom) 102{ 103 104 105 // 106 // seedrandom() 107 // This is the seedrandom function described above. 108 // 109 math['seedrandom'] = function seedrandom(seed, use_entropy) 110 { 111 var key = []; 112 var arc4; 113 114 // Flatten the seed string or build one from local entropy if needed. 115 seed = mixkey(flatten( 116 use_entropy ? [seed, pool] : arguments.length ? seed : [new Date().getTime(), pool, window], 3), key); 117 118 // Use the seed to initialize an ARC4 generator. 119 arc4 = new ARC4(key); 120 121 // Mix the randomness into accumulated entropy. 122 mixkey(arc4.S, pool); 123 124 // Override Math.random 125 // This function returns a random double in [0, 1) that contains 126 // randomness in every bit of the mantissa of the IEEE 754 value. 127 math['random'] = function random() 128 { // Closure to return a random double: 129 var n = arc4.g(chunks); // Start with a numerator n < 2 ^ 48 130 var d = startdenom; // and denominator d = 2 ^ 48. 131 var x = 0; // and no 'extra last byte'. 132 while (n < significance) 133 { // Fill up all significant digits by 134 n = (n + x) * width; // shifting numerator and 135 d *= width; // denominator and generating a 136 x = arc4.g(1); // new least-significant-byte. 137 } 138 while (n >= overflow) 139 { // To avoid rounding up, before adding 140 n /= 2; // last byte, shift everything 141 d /= 2; // right using integer math until 142 x >>>= 1; // we have exactly the desired bits. 143 } 144 return (n + x) / d; // Form the number within [0, 1). 145 }; 146 147 // Return the seed that was used 148 return seed; 149 }; 150 151 // 152 // ARC4 153 // 154 // An ARC4 implementation. The constructor takes a key in the form of 155 // an array of at most (width) integers that should be 0 <= x < (width). 156 // 157 // The g(count) method returns a pseudorandom integer that concatenates 158 // the next (count) outputs from ARC4. Its return value is a number x 159 // that is in the range 0 <= x < (width ^ count). 160 // 161 /** @constructor */ 162 163 function ARC4(key) 164 { 165 var t, u, me = this, 166 keylen = key.length; 167 var i = 0, 168 j = me.i = me.j = me.m = 0; 169 me.S = []; 170 me.c = []; 171 172 // The empty key [] is treated as [0]. 173 if (!keylen) 174 { 175 key = [keylen++]; 176 } 177 178 // Set up S using the standard key scheduling algorithm. 179 while (i < width) 180 { 181 me.S[i] = i++; 182 } 183 for (i = 0; i < width; i++) 184 { 185 t = me.S[i]; 186 j = lowbits(j + t + key[i % keylen]); 187 u = me.S[j]; 188 me.S[i] = u; 189 me.S[j] = t; 190 } 191 192 // The "g" method returns the next (count) outputs as one number. 193 me.g = function getnext(count) 194 { 195 var s = me.S; 196 var i = lowbits(me.i + 1); 197 var t = s[i]; 198 var j = lowbits(me.j + t); 199 var u = s[j]; 200 s[i] = u; 201 s[j] = t; 202 var r = s[lowbits(t + u)]; 203 while (--count) 204 { 205 i = lowbits(i + 1); 206 t = s[i]; 207 j = lowbits(j + t); 208 u = s[j]; 209 s[i] = u; 210 s[j] = t; 211 r = r * width + s[lowbits(t + u)]; 212 } 213 me.i = i; 214 me.j = j; 215 return r; 216 }; 217 // For robust unpredictability discard an initial batch of values. 218 // See http://www.rsa.com/rsalabs/node.asp?id=2009 219 me.g(width); 220 } 221 222 // 223 // flatten()
224 // Converts an object tree to nested arrays of strings. 225 // 226 /** @param {Object=} result 227 * @param {string=} prop 228 * @param {string=} typ */ 229 230 function flatten(obj, depth, result, prop, typ) 231 { 232 result = []; 233 typ = typeof (obj); 234 if (depth && typ == 'object') 235 { 236 for (prop in obj) 237 { 238 if (prop.indexOf('S') < 5) 239 { // Avoid FF3 bug (local/sessionStorage) 240 try 241 { 242 result.push(flatten(obj[prop], depth - 1)); 243 } 244 catch (e) 245 {} 246 } 247 } 248 } 249 return (result.length ? result : obj + (typ != 'string' ? '\0' : '')); 250 } 251 252 // 253 // mixkey() 254 // Mixes a string seed into a key that is an array of integers, and 255 // returns a shortened string seed that is equivalent to the result key. 256 // 257 /** @param {number=} smear 258 * @param {number=} j */ 259 260 function mixkey(seed, key, smear, j) 261 { 262 seed += ''; // Ensure the seed is a string 263 smear = 0; 264 for (j = 0; j < seed.length; j++) 265 { 266 key[lowbits(j)] = lowbits((smear ^= key[lowbits(j)] * 19) + seed.charCodeAt(j)); 267 } 268 seed = ''; 269 for (j in key) 270 { 271 seed += String.fromCharCode(key[j]); 272 } 273 return seed; 274 } 275 276 // 277 // lowbits() 278 // A quick "n mod width" for width a power of 2. 279 // 280 281 282 function lowbits(n) 283 { 284 return n & (width - 1); 285 } 286 287 // 288 // The following constants are related to IEEE 754 limits. 289 // 290 startdenom = math.pow(width, chunks); 291 significance = math.pow(2, significance); 292 overflow = significance * 2; 293 294 // 295 // When seedrandom.js is loaded, we immediately mix a few bits 296 // from the built-in RNG into the entropy pool. Because we do 297 // not want to intefere with determinstic PRNG state later, 298 // seedrandom will not call math.random on its own again after 299 // initialization. 300 // 301 mixkey(math.random(), pool); 302 303 // End anonymous scope, and pass initial values. 304})([], // pool: entropy pool starts empty 305Math, // math: package containing random, pow, and seedrandom 306256, // width: each RC4 output is 0 <= x < 256 3076, // chunks: at least six RC4 outputs for each double 30852 // significance: there are 52 significant digits in a double 309); 310 311 312// This is not really a random number generator object, and two SeededRandom 313// objects will conflict with one another, but it's good enough for generating 314// the rsa key. 315function SeededRandom(){} 316 317function SRnextBytes(ba) 318{ 319 var i; 320 for(i = 0; i < ba.length; i++) 321 { 322 ba[i] = Math.floor(Math.random() * 256); 323 } 324} 325 326SeededRandom.prototype.nextBytes = SRnextBytes; 327 328// prng4.js - uses Arcfour as a PRNG 329 330function Arcfour() { 331 this.i = 0; 332 this.j = 0; 333 this.S = new Array(); 334} 335 336// Initialize arcfour context from key, an array of ints, each from [0..255] 337function ARC4init(key) { 338 var i, j, t; 339 for(i = 0; i < 256; ++i) 340 this.S[i] = i; 341 j = 0; 342 for(i = 0; i < 256; ++i) { 343 j = (j + this.S[i] + key[i % key.length]) & 255; 344 t = this.S[i]; 345 this.S[i] = this.S[j]; 346 this.S[j] = t; 347 } 348 this.i = 0; 349 this.j = 0; 350} 351 352function ARC4next() { 353 var t; 354 this.i = (this.i + 1) & 255; 355 this.j = (this.j + this.S[this.i]) & 255; 356 t = this.S[this.i]; 357 this.S[this.i] = this.S[this.j]; 358 this.S[this.j] = t; 359 return this.S[(t + this.S[this.i]) & 255]; 360} 361 362Arcfour.prototype.init = ARC4init; 363Arcfour.prototype.next = ARC4next; 364 365// Plug in your RNG constructor here 366function prng_newstate() { 367 return new Arcfour(); 368} 369 370// Pool size must be a multiple of 4 and greater than 32. 371// An array of bytes the size of the pool will be passed to init() 372var rng_psize = 256; 373 374// Random number generator - requires a PRNG backend, e.g. prng4.js 375 376// For best results, put code like 377// <body onClick='rng_seed_time();' onKeyPress='rng_seed_time();'> 378// in your main HTML document. 379 380var rng_state; 381var rng_pool; 382var rng_pptr; 383 384// Mix in a 32-bit integer into the pool 385function rng_seed_int(x) { 386 rng_pool[rng_pptr++] ^= x & 255; 387 rng_pool[rng_pptr++] ^= (x >> 8) & 255; 388 rng_pool[rng_pptr++] ^= (x >> 16) & 255; 389 rng_pool[rng_pptr++] ^= (x >> 24) & 255; 390 if(rng_pptr >= rng_psize) rng_pptr -= rng_psize; 391} 392 393// Mix in the current time (w/milliseconds) into the pool 394function rng_seed_time() { 395 rng_seed_int(new Date().getTime()); 396} 397 398// Initialize the pool with junk if needed. 399if(rng_pool == null) { 400 rng_pool = new Array(); 401 rng_pptr = 0; 402 var t; 403 if(navigator.appName == "Netscape" && navigator.appVersion < "5" && window.crypto) { 404 // Extract entropy (256 bits) from NS4 RNG if available 405 var z = window.crypto.random(32); 406 for(t = 0; t < z.length; ++t) 407 rng_pool[rng_pptr++] = z.charCodeAt(t) & 255; 408 } 409 while(rng_pptr < rng_psize) { // extract some randomness from Math.random() 410 t = Math.floor(65536 * Math.random()); 411 rng_pool[rng_pptr++] = t >>> 8; 412 rng_pool[rng_pptr++] = t & 255; 413 } 414 rng_pptr = 0; 415 rng_seed_time(); 416 //rng_seed_int(window.screenX); 417 //rng_seed_int(window.screenY); 418} 419 420function rng_get_byte() { 421 if(rng_state == null) { 422 rng_seed_time(); 423 rng_state = prng_newstate(); 424 rng_state.init(rng_pool); 425 for(rng_pptr = 0; rng_pptr < rng_pool.length; ++rng_pptr) 426 rng_pool[rng_pptr] = 0; 427 rng_pptr = 0; 428 //rng_pool = null; 429 } 430 // TODO: allow reseeding after first request 431 return rng_state.next(); 432} 433 434function rng_get_bytes(ba) { 435 var i; 436 for(i = 0; i < ba.length; ++i) ba[i] = rng_get_byte(); 437} 438 439function SecureRandom() {} 440 441SecureRandom.prototype.nextBytes = rng_get_bytes; 442 443 444 445 446 447
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.