dbb38b4c65e2af10085136b1c8c7640da1212346
[jalviewjs.git] / site / j2s / java / util / Random.js
1 Clazz.load(null,"java.util.Random",["java.lang.IllegalArgumentException"],function(){\r
2 c$=Clazz.decorateAsClass(function(){\r
3 this.haveNextNextGaussian=false;\r
4 this.seed=0;\r
5 this.nextNextGaussian=0;\r
6 Clazz.instantialize(this,arguments);\r
7 },java.util,"Random",null,java.io.Serializable);\r
8 Clazz.makeConstructor(c$,\r
9 function(){\r
10 this.setSeed(System.currentTimeMillis());\r
11 });\r
12 Clazz.makeConstructor(c$,\r
13 function(seed){\r
14 this.setSeed(seed);\r
15 },"~N");\r
16 Clazz.defineMethod(c$,"next",\r
17 function(bits){\r
18 this.seed=(this.seed*25214903917+0xb)&(281474976710655);\r
19 return(this.seed>>>(48-bits));\r
20 },"~N");\r
21 Clazz.defineMethod(c$,"nextBoolean",\r
22 function(){\r
23 return Math.random()>0.5;\r
24 });\r
25 Clazz.defineMethod(c$,"nextBytes",\r
26 function(buf){\r
27 for(var i=0;i<bytes.length;i++){\r
28 bytes[i]=Math.round(0x100*Math.random());\r
29 }\r
30 },"~A");\r
31 Clazz.defineMethod(c$,"nextDouble",\r
32 function(){\r
33 return Math.random();\r
34 });\r
35 Clazz.defineMethod(c$,"nextFloat",\r
36 function(){\r
37 return Math.random();\r
38 });\r
39 Clazz.defineMethod(c$,"nextGaussian",\r
40 function(){\r
41 if(this.haveNextNextGaussian){\r
42 this.haveNextNextGaussian=false;\r
43 return this.nextNextGaussian;\r
44 }var v1;\r
45 var v2;\r
46 var s;\r
47 do{\r
48 v1=2*this.nextDouble()-1;\r
49 v2=2*this.nextDouble()-1;\r
50 s=v1*v1+v2*v2;\r
51 }while(s>=1);\r
52 var norm=Math.sqrt(-2*Math.log(s)/s);\r
53 this.nextNextGaussian=v2*norm;\r
54 this.haveNextNextGaussian=true;\r
55 return v1*norm;\r
56 });\r
57 Clazz.defineMethod(c$,"nextInt",\r
58 function(){\r
59 return Math.ceil(0xffff*Math.random())-0x8000;\r
60 });\r
61 Clazz.defineMethod(c$,"nextInt",\r
62 function(n){\r
63 if(n>0){\r
64 n = Math.min(n, 31);\r
65 return Math.floor((2 << (n - 1)) * Math.random())\r
66 \r
67 /*\r
68 if((n&-n)==n){\r
69 return((n*this.next(31))>>31);\r
70 }var bits;\r
71 var val;\r
72 do{\r
73 bits=this.next(31);\r
74 val=bits%n;\r
75 }while(bits-val+(n-1)<0);\r
76 \r
77 \r
78 return val;\r
79 \r
80 */\r
81 }\r
82 throw new IllegalArgumentException();\r
83 },"~N");\r
84 Clazz.defineMethod(c$,"nextLong",\r
85 function(){\r
86 return Math.ceil(0xffffffff*Math.random())-0x80000000;\r
87 });\r
88 Clazz.defineMethod(c$,"setSeed",\r
89 function(seed){\r
90 Math.seedrandom(seed);\r
91 //this.seed=(seed^25214903917)&(281474976710655);\r
92 //this.haveNextNextGaussian=false;\r
93 },"~N");\r
94 Clazz.defineStatics(c$,\r
95 "multiplier",0x5deece66d);\r
96 });\r
97 \r
98 // seedrandom.js\r
99 // Author: David Bau 3/11/2010\r
100 //\r
101 // Defines a method Math.seedrandom() that, when called, substitutes\r
102 // an explicitly seeded RC4-based algorithm for Math.random().  Also\r
103 // supports automatic seeding from local or network sources of entropy.\r
104 //\r
105 // Usage:\r
106 //\r
107 //   <script src=http://davidbau.com/encode/seedrandom-min.js></script>\r
108 //\r
109 //   Math.seedrandom('yipee'); Sets Math.random to a function that is\r
110 //                             initialized using the given explicit seed.\r
111 //\r
112 //   Math.seedrandom();        Sets Math.random to a function that is\r
113 //                             seeded using the current time, dom state,\r
114 //                             and other accumulated local entropy.\r
115 //                             The generated seed string is returned.\r
116 //\r
117 //   Math.seedrandom('yowza', true);\r
118 //                             Seeds using the given explicit seed mixed\r
119 //                             together with accumulated entropy.\r
120 //\r
121 //   <script src="http://bit.ly/srandom-512"></script>\r
122 //                             Seeds using physical random bits downloaded\r
123 //                             from random.org.\r
124 //\r
125 // Examples:\r
126 //\r
127 //   Math.seedrandom("hello");            // Use "hello" as the seed.\r
128 //   document.write(Math.random());       // Always 0.5463663768140734\r
129 //   document.write(Math.random());       // Always 0.43973793770592234\r
130 //   var rng1 = Math.random;              // Remember the current prng.\r
131 //\r
132 //   var autoseed = Math.seedrandom();    // New prng with an automatic seed.\r
133 //   document.write(Math.random());       // Pretty much unpredictable.\r
134 //\r
135 //   Math.random = rng1;                  // Continue "hello" prng sequence.\r
136 //   document.write(Math.random());       // Always 0.554769432473455\r
137 //\r
138 //   Math.seedrandom(autoseed);           // Restart at the previous seed.\r
139 //   document.write(Math.random());       // Repeat the 'unpredictable' value.\r
140 //\r
141 // Notes:\r
142 //\r
143 // Each time seedrandom('arg') is called, entropy from the passed seed\r
144 // is accumulated in a pool to help generate future seeds for the\r
145 // zero-argument form of Math.seedrandom, so entropy can be injected over\r
146 // time by calling seedrandom with explicit data repeatedly.\r
147 //\r
148 // On speed - This javascript implementation of Math.random() is about\r
149 // 3-10x slower than the built-in Math.random() because it is not native\r
150 // code, but this is typically fast enough anyway.  Seeding is more expensive,\r
151 // especially if you use auto-seeding.  Some details (timings on Chrome 4):\r
152 //\r
153 // Our Math.random()            - avg less than 0.002 milliseconds per call\r
154 // seedrandom('explicit')       - avg less than 0.5 milliseconds per call\r
155 // seedrandom('explicit', true) - avg less than 2 milliseconds per call\r
156 // seedrandom()                 - avg about 38 milliseconds per call\r
157 //\r
158 // LICENSE (BSD):\r
159 //\r
160 // Copyright 2010 David Bau, all rights reserved.\r
161 //\r
162 // Redistribution and use in source and binary forms, with or without\r
163 // modification, are permitted provided that the following conditions are met:\r
164 //\r
165 //   1. Redistributions of source code must retain the above copyright\r
166 //      notice, this list of conditions and the following disclaimer.\r
167 //\r
168 //   2. Redistributions in binary form must reproduce the above copyright\r
169 //      notice, this list of conditions and the following disclaimer in the\r
170 //      documentation and/or other materials provided with the distribution.\r
171 //\r
172 //   3. Neither the name of this module nor the names of its contributors may\r
173 //      be used to endorse or promote products derived from this software\r
174 //      without specific prior written permission.\r
175 //\r
176 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\r
177 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\r
178 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\r
179 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\r
180 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\r
181 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\r
182 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\r
183 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\r
184 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\r
185 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\r
186 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\r
187 //\r
188 /**\r
189  * All code is in an anonymous closure to keep the global namespace clean.\r
190  *\r
191  * @param {number=} overflow\r
192  * @param {number=} startdenom\r
193  */\r
194 (function (pool, math, width, chunks, significance, overflow, startdenom) {\r
195 \r
196 var copyright = "Copyright 2010 David Bau, all rights reserved. (BSD)"\r
197 //\r
198 // seedrandom()\r
199 // This is the seedrandom function described above.\r
200 //\r
201 math['seedrandom'] = function seedrandom(seed, use_entropy) {\r
202   var key = [];\r
203   var arc4;\r
204 \r
205   // Flatten the seed string or build one from local entropy if needed.\r
206   seed = mixkey(flatten(\r
207     use_entropy ? [seed, pool] :\r
208     arguments.length ? seed :\r
209     [new Date().getTime(), pool, window], 3), key);\r
210 \r
211   // Use the seed to initialize an ARC4 generator.\r
212   arc4 = new ARC4(key);\r
213 \r
214   // Mix the randomness into accumulated entropy.\r
215   mixkey(arc4.S, pool);\r
216 \r
217   // Override Math.random\r
218 \r
219   // This function returns a random double in [0, 1) that contains\r
220   // randomness in every bit of the mantissa of the IEEE 754 value.\r
221 \r
222   math['random'] = function random() {  // Closure to return a random double:\r
223     var n = arc4.g(chunks);             // Start with a numerator n < 2 ^ 48\r
224     var d = startdenom;                 //   and denominator d = 2 ^ 48.\r
225     var x = 0;                          //   and no 'extra last byte'.\r
226     while (n < significance) {          // Fill up all significant digits by\r
227       n = (n + x) * width;              //   shifting numerator and\r
228       d *= width;                       //   denominator and generating a\r
229       x = arc4.g(1);                    //   new least-significant-byte.\r
230     }\r
231     while (n >= overflow) {             // To avoid rounding up, before adding\r
232       n /= 2;                           //   last byte, shift everything\r
233       d /= 2;                           //   right using integer math until\r
234       x >>>= 1;                         //   we have exactly the desired bits.\r
235     }\r
236     return (n + x) / d;                 // Form the number within [0, 1).\r
237   };\r
238 \r
239   // Return the seed that was used\r
240   return seed;\r
241 };\r
242 \r
243 //\r
244 // ARC4\r
245 //\r
246 // An ARC4 implementation.  The constructor takes a key in the form of\r
247 // an array of at most (width) integers that should be 0 <= x < (width).\r
248 //\r
249 // The g(count) method returns a pseudorandom integer that concatenates\r
250 // the next (count) outputs from ARC4.  Its return value is a number x\r
251 // that is in the range 0 <= x < (width ^ count).\r
252 //\r
253 /** @constructor */\r
254 function ARC4(key) {\r
255   var t, u, me = this, keylen = key.length;\r
256   var i = 0, j = me.i = me.j = me.m = 0;\r
257   me.S = [];\r
258   me.c = [];\r
259 \r
260   // The empty key [] is treated as [0].\r
261   if (!keylen) { key = [keylen++]; }\r
262 \r
263   // Set up S using the standard key scheduling algorithm.\r
264   while (i < width) { me.S[i] = i++; }\r
265   for (i = 0; i < width; i++) {\r
266     t = me.S[i];\r
267     j = lowbits(j + t + key[i % keylen]);\r
268     u = me.S[j];\r
269     me.S[i] = u;\r
270     me.S[j] = t;\r
271   }\r
272 \r
273   // The "g" method returns the next (count) outputs as one number.\r
274   me.g = function getnext(count) {\r
275     var s = me.S;\r
276     var i = lowbits(me.i + 1); var t = s[i];\r
277     var j = lowbits(me.j + t); var u = s[j];\r
278     s[i] = u;\r
279     s[j] = t;\r
280     var r = s[lowbits(t + u)];\r
281     while (--count) {\r
282       i = lowbits(i + 1); t = s[i];\r
283       j = lowbits(j + t); u = s[j];\r
284       s[i] = u;\r
285       s[j] = t;\r
286       r = r * width + s[lowbits(t + u)];\r
287     }\r
288     me.i = i;\r
289     me.j = j;\r
290     return r;\r
291   };\r
292   // For robust unpredictability discard an initial batch of values.\r
293   // See http://www.rsa.com/rsalabs/node.asp?id=2009\r
294   me.g(width);\r
295 }\r
296 \r
297 //\r
298 // flatten()\r
299 // Converts an object tree to nested arrays of strings.\r
300 //\r
301 /** @param {Object=} result\r
302   * @param {string=} prop */\r
303 function flatten(obj, depth, result, prop) {\r
304   result = [];\r
305   if (depth && typeof(obj) == 'object') {\r
306     for (prop in obj) {\r
307       if (prop.indexOf('S') < 5) {    // Avoid FF3 bug (local/sessionStorage)\r
308         try { result.push(flatten(obj[prop], depth - 1)); } catch (e) {}\r
309       }\r
310     }\r
311   }\r
312   return result.length ? result : '' + obj;\r
313 }\r
314 \r
315 //\r
316 // mixkey()\r
317 // Mixes a string seed into a key that is an array of integers, and\r
318 // returns a shortened string seed that is equivalent to the result key.\r
319 //\r
320 /** @param {number=} smear\r
321   * @param {number=} j */\r
322 function mixkey(seed, key, smear, j) {\r
323   seed += '';                         // Ensure the seed is a string\r
324   smear = 0;\r
325   for (j = 0; j < seed.length; j++) {\r
326     key[lowbits(j)] =\r
327       lowbits((smear ^= key[lowbits(j)] * 19) + seed.charCodeAt(j));\r
328   }\r
329   seed = '';\r
330   for (j in key) { seed += String.fromCharCode(key[j]); }\r
331   return seed;\r
332 }\r
333 \r
334 //\r
335 // lowbits()\r
336 // A quick "n mod width" for width a power of 2.\r
337 //\r
338 function lowbits(n) { return n & (width - 1); }\r
339 \r
340 //\r
341 // The following constants are related to IEEE 754 limits.\r
342 //\r
343 startdenom = math.pow(width, chunks);\r
344 significance = math.pow(2, significance);\r
345 overflow = significance * 2;\r
346 \r
347 //\r
348 // When seedrandom.js is loaded, we immediately mix a few bits\r
349 // from the built-in RNG into the entropy pool.  Because we do\r
350 // not want to intefere with determinstic PRNG state later,\r
351 // seedrandom will not call math.random on its own again after\r
352 // initialization.\r
353 //\r
354 mixkey(math.random(), pool);\r
355 \r
356 // End anonymous scope, and pass initial values.\r
357 })(\r
358   [],   // pool: entropy pool starts empty\r
359   Math, // math: package containing random, pow, and seedrandom\r
360   256,  // width: each RC4 output is 0 <= x < 256\r
361   6,    // chunks: at least six RC4 outputs for each double\r
362   52    // significance: there are 52 significant digits in a double\r
363 );\r
364 \r