View difference between Paste ID: YHib4W57 and F6Ahw0ND
SHOW: | | - or go back to the newest paste.
1
/**
2-
 *	Class: XORShiftPlus: "non-linear" PRNG
2+
 *  XORShiftPlus "non-linear" PRNG
3-
 *	Author: k98kurz (@gmail)
3+
 *  Author: k98kurz (@gmail)
4-
 *	License: MIT
4+
 *  License: MIT
5-
 *	Description: Based upon the xorshift128+ generator, one of the fastest generators passing BigCrush.
5+
 *  Date: 2020-09-07
6-
 *	Methods:
6+
 *  Description: Based upon the xorshift128+ generator, one of the fastest generators passing BigCrush.
7-
 *		next(n)			returns Uint32Array of n random numbers
7+
 *  Methods:
8-
 *		nextHex(n)		returns Array of n hexidecimal numbers
8+
 *      next(n)         returns Uint32Array of n random numbers
9-
 *		bytes(n)		returns Uint8Array of n random bytes
9+
 *      nextHex(n)      returns Array of n hexidecimal numbers
10-
 *		bytesHex(n)		returns Array of n random bytes in hexidecimal
10+
 *      bytes(n)        returns Uint8Array of n random bytes
11-
 *		hex(n)			returns hexidecimal string of n bytes
11+
 *      bytesHex(n)     returns Array of n random bytes in hexidecimal
12
 *      hex(n)          returns hexidecimal string of n bytes
13-
function XORShiftPlus (seed) {
13+
 *  Note: This generates with higher periodicity and better random distribution than the linear XORShift.
14-
	var x = new Uint32Array(1), y = new Uint32Array(1), z = new Uint32Array(1), w = new Uint32Array(1);
14+
15-
	x[0] = seed ? seed|0 : 317973455;
15+
class XORShiftPlus {
16-
	y[0] = x[0]<<362436069;
16+
  #booted = false;
17-
	z[0] = y[0]+x[0];
17+
  #x;
18-
	w[0] = z[0]^x[0]+y[0];
18+
  #y;
19
  #z;
20-
	function next () {
20+
  #w;
21-
		var t = new Uint32Array(1);
21+
22-
		t[0] = x[0]^(x<<11);
22+
  constructor (seed) {
23-
		x[0] = y[0]; y[0] = z[0]; z[0] = w[0];
23+
    this.#x = new Uint32Array(1);
24-
		w[0] = w[0]^(w[0]>>19)^(t[0]^(t[0]>>8));
24+
    this.#y = new Uint32Array(1);
25-
		return w[0]+y[0];
25+
    this.#z = new Uint32Array(1);
26-
	}
26+
    this.#w = new Uint32Array(1);
27
    this.#x[0] = seed ? seed|0 : 317973455;
28-
	// discard the first numbers as they are somewhat predictable
28+
    this.#y[0] = this.#x[0]<<362436069;
29-
	for (var i=0, n=next(), j=next()%256; i<=j; next(), ++i);
29+
    this.#z[0] = this.#y[0]+this.#x[0];
30
    this.#w[0] = this.#z[0]^this.#x[0]+this.#y[0];
31-
	this.next = function (n, option) {
31+
  }
32-
		if (typeof n == 'undefined' || typeof n !== 'number')
32+
33-
			var n = 1;
33+
  #next () {
34-
		var t; n |= 0; n = n>0 ? n : 1;
34+
    let t = new Uint32Array(1);
35-
		if (typeof option == 'undefined' || typeof n !== 'number')
35+
    t[0] = this.#x[0]^(this.#x[0]<<11);
36-
			var option = 0;
36+
    this.#x[0] = this.#y[0];
37
    this.#y[0] = this.#z[0];
38-
		// redundant code, but improved performance
38+
    this.#z[0] = this.#w[0];
39-
		switch (option) {
39+
    this.#w[0] = this.#w[0]^(this.#w[0]>>19)^(t[0]^(t[0]>>8));
40-
			// nextHex
40+
    return this.#w[0]+this.#y[0];
41-
			case 1:
41+
  }
42-
				t = [];
42+
43-
				for (var i=0, il=n; i<il; t[i++] = next().toString(16));
43+
  #boot () {
44-
				break;
44+
    // if not booted, discard the first numbers as they are somewhat predictable
45-
			// bytes
45+
    if (this.#booted)
46-
			case 2:
46+
      return;
47-
				t = new Uint8Array(n);
47+
    for (let i=0, n=this.#next(), j=this.#next()%256; i<=j; this.#next(), ++i);
48-
				for (var i=0, il=n; i<il; t[i++] = next());
48+
    this.#booted = true;
49-
				break;
49+
  }
50-
			// bytesHex
50+
51-
			case 3:
51+
  next (n, option) {
52-
				t = [];
52+
    this.#boot();
53-
				for (var i=0, il=n; i<il; t[i] = (next()%256).toString(16), t[i] = t[i].length%2 ? '0'+t[i] : t[i], ++i);
53+
    n = (n === undefined || typeof n !== 'number') ? 1 : n;
54-
				break;
54+
    let t; n |= 0; n = n>0 ? n : 1;
55-
			// hex
55+
    option = (option === undefined || typeof n !== 'number') ? 0 : option;
56-
			case 4:
56+
57-
				t = [];
57+
    // redundant code, but improved performance
58-
				for (var i=0, il=n; i<il; t[i] = (next()%256).toString(16), t[i] = t[i].length%2 ? '0'+t[i] : t[i], ++i);
58+
    switch (option) {
59-
				t = t.join('');
59+
      // nextHex
60-
				break;
60+
      case 1:
61-
			// next
61+
        t = [];
62-
			default:
62+
        for (let i=0, il=n; i<il; t[i++] = this.#next().toString(16));
63-
				t = new Uint32Array(n);
63+
        break;
64-
				for (var i=0, il=n; i<il; t[i++] = next());
64+
      // bytes
65-
		}
65+
      case 2:
66
        t = new Uint8Array(n);
67-
		return t;
67+
        for (let i=0, il=n; i<il; t[i++] = this.#next());
68-
	};
68+
        break;
69
      // bytesHex
70-
	this.nextHex = function (n) { return this.next(n, 1); };
70+
      case 3:
71
        t = [];
72-
	this.bytes = function (n) { return this.next(n, 2); };
72+
        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);
73
        break;
74-
	this.bytesHex = function (n) { return this.next(n, 3); };
74+
      // hex
75
      case 4:
76-
	this.hex = function (n) { return this.next(n, 4); };
76+
        t = [];
77
        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);
78-
	this.nextMod = function (m, n) {
78+
        t = t.join('');
79-
		var t = this.next(n ? n|0 : 1, 0);
79+
        break;
80-
		if (typeof n == "number" && !isNaN(n) && n > 1) {
80+
      // next
81-
			m = (typeof m == "number") ? m|0 : Number.MAX_SAFE_INTEGER;
81+
      default:
82-
			for (var i=0, il=t.length; i<il; ++i) {
82+
        t = new Uint32Array(n);
83-
			    t[i] = t[i] % m;
83+
        for (let i=0, il=n; i<il; t[i++] = this.#next());
84-
			}
84+
    }
85-
			return t;
85+
    return t;
86-
		}
86+
  };
87-
		return m ? t % (m|0) : t;
87+
88-
	}
88+
  nextHex (n) { return this.next(n, 1); };
89
90
  bytes (n) { return this.next(n, 2); };
91
92
  bytesHex (n) { return this.next(n, 3); };
93
94
  hex (n) { return this.next(n, 4); };
95
}