Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- /**
- * XORShiftPlus "non-linear" PRNG
- * Author: k98kurz (@gmail)
- * License: MIT
- * Date: 2020-09-07
- * Description: Based upon the xorshift128+ generator, one of the fastest generators passing BigCrush.
- * Methods:
- * next(n) returns Uint32Array of n random numbers
- * nextHex(n) returns Array of n hexidecimal numbers
- * bytes(n) returns Uint8Array of n random bytes
- * bytesHex(n) returns Array of n random bytes in hexidecimal
- * hex(n) returns hexidecimal string of n bytes
- * Note: This generates with higher periodicity and better random distribution than the linear XORShift.
- */
- class XORShiftPlus {
- #booted = false;
- #x;
- #y;
- #z;
- #w;
- constructor (seed) {
- this.#x = new Uint32Array(1);
- this.#y = new Uint32Array(1);
- this.#z = new Uint32Array(1);
- this.#w = new Uint32Array(1);
- this.#x[0] = seed ? seed|0 : 317973455;
- this.#y[0] = this.#x[0]<<362436069;
- this.#z[0] = this.#y[0]+this.#x[0];
- this.#w[0] = this.#z[0]^this.#x[0]+this.#y[0];
- }
- #next () {
- let t = new Uint32Array(1);
- t[0] = this.#x[0]^(this.#x[0]<<11);
- this.#x[0] = this.#y[0];
- this.#y[0] = this.#z[0];
- this.#z[0] = this.#w[0];
- this.#w[0] = this.#w[0]^(this.#w[0]>>19)^(t[0]^(t[0]>>8));
- return this.#w[0]+this.#y[0];
- }
- #boot () {
- // if not booted, discard the first numbers as they are somewhat predictable
- if (this.#booted)
- return;
- for (let i=0, n=this.#next(), j=this.#next()%256; i<=j; this.#next(), ++i);
- this.#booted = true;
- }
- next (n, option) {
- this.#boot();
- n = (n === undefined || typeof n !== 'number') ? 1 : n;
- let t; n |= 0; n = n>0 ? n : 1;
- option = (option === undefined || typeof n !== 'number') ? 0 : option;
- // redundant code, but improved performance
- switch (option) {
- // nextHex
- case 1:
- t = [];
- for (let i=0, il=n; i<il; t[i++] = this.#next().toString(16));
- break;
- // bytes
- case 2:
- t = new Uint8Array(n);
- for (let i=0, il=n; i<il; t[i++] = this.#next());
- break;
- // bytesHex
- case 3:
- t = [];
- for (let i=0, il=n; i<il; t[i] = (this.#next()%256).toString(16), t[i] = t[i].length%2 ? '0'+t[i] : t[i], ++i);
- break;
- // hex
- case 4:
- t = [];
- for (let i=0, il=n; i<il; t[i] = (this.#next()%256).toString(16), t[i] = t[i].length%2 ? '0'+t[i] : t[i], ++i);
- t = t.join('');
- break;
- // next
- default:
- t = new Uint32Array(n);
- for (let i=0, il=n; i<il; t[i++] = this.#next());
- }
- return t;
- };
- nextHex (n) { return this.next(n, 1); };
- bytes (n) { return this.next(n, 2); };
- bytesHex (n) { return this.next(n, 3); };
- hex (n) { return this.next(n, 4); };
- }
Add Comment
Please, Sign In to add comment