Skip to content

Commit dd8ebc2

Browse files
committed
updated xor128
1 parent 3465c6b commit dd8ebc2

File tree

2 files changed

+116
-10
lines changed

2 files changed

+116
-10
lines changed

README.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,8 @@ Just clone the repo or download the last release.
88

99
## Cool. Do you have some documentation?
1010

11-
[Yes, here.](https://lorossi.github.io/empty-html5-canvas-project/).
11+
[Yes, here](https://lorossi.github.io/empty-html5-canvas-project/).
12+
Documentation for the XOR128 random number generator is [here](https://lorossi.github.io/js-XOR128).
1213

1314
Don't have time for that?
1415
Keep reading for the short version.

js/xor128.js

Lines changed: 114 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
/**
22
* XOR128 js implementation
3-
* @version 1.0.0
3+
* @version 1.1.0
44
* @author Lorenzo Rossi - https://www.lorenzoros.si - https://github.com/lorossi/
55
* @license MIT
66
*/
@@ -12,17 +12,47 @@ class XOR128 {
1212
* All parameters are optional, if nothing is passed a random value from
1313
* js functions Math.random() will be used
1414
*
15-
* @param {number} [x] first seed
15+
* @param {number|Array} [x] first seed or array of seeds. \
16+
* If an array is passed, the first 4 elements will be used as seeds
1617
* @param {number} [y] second seed
1718
* @param {number} [z] third seed
1819
* @param {number} [w] fourth seed
1920
* @returns {XOR128}
2021
*/
2122
constructor(x = null, y = null, z = null, w = null) {
22-
if (x == null || x == undefined) x = Math.floor(Math.random() * 4294967296);
23-
if (y == null || x == undefined) y = Math.floor(Math.random() * 4294967296);
24-
if (z == null || x == undefined) z = Math.floor(Math.random() * 4294967296);
25-
if (w == null || x == undefined) w = Math.floor(Math.random() * 4294967296);
23+
if (x instanceof Array) {
24+
if (x.length > 4) throw new Error("XOR128: too many seeds");
25+
26+
for (let i = x.length; i < 4; i++) x.push(x[i - 1] + 1);
27+
28+
return new XOR128(x[0], x[1], x[2], x[3]);
29+
}
30+
31+
if (x == null) x = Math.floor(Math.random() * 4294967296);
32+
33+
if (y == null) {
34+
if (x != null) {
35+
y = x + 1;
36+
} else {
37+
y = Math.floor(Math.random() * 4294967296);
38+
}
39+
}
40+
41+
if (z == null) {
42+
if (y != null) {
43+
z = y + 1;
44+
} else {
45+
z = Math.floor(Math.random() * 4294967296);
46+
}
47+
}
48+
49+
if (w == null) {
50+
if (z != null) {
51+
w = z + 1;
52+
} else {
53+
w = Math.floor(Math.random() * 4294967296);
54+
}
55+
}
2656

2757
if (
2858
typeof x !== "number" ||
@@ -35,6 +65,8 @@ class XOR128 {
3565
if (x < 1 || y < 1 || z < 1 || w < 1)
3666
throw new Error("XOR128: seed values must be greater than 0");
3767

68+
if (arguments.length > 4) throw new Error("XOR128: too many arguments");
69+
3870
this._x = x;
3971
this._y = y;
4072
this._z = z;
@@ -59,6 +91,12 @@ class XOR128 {
5991
a = 0;
6092
}
6193

94+
if (a > b)
95+
throw new Error("XOR128: first parameter must be smaller than second");
96+
97+
if (!(typeof a === "number" && typeof b === "number"))
98+
throw new Error("XOR128: parameters must be numbers");
99+
62100
const t = this._x ^ ((this._x << 11) >>> 0);
63101

64102
this._x = this._y;
@@ -87,7 +125,34 @@ class XOR128 {
87125
a = 0;
88126
}
89127

90-
return Math.floor(this.random(a, b + 1));
128+
return Math.floor(this.random(a, b));
129+
}
130+
131+
/**
132+
* Returns a random boolean
133+
*
134+
* @returns {Boolean} random boolean
135+
*/
136+
random_bool() {
137+
return this.random() > 0.5;
138+
}
139+
140+
/**
141+
* Returns a random string
142+
*
143+
* @param {number} [length=10] length of the string
144+
* @param {string} [chars="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"] characters to use
145+
*/
146+
random_string(
147+
length = 10,
148+
chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"
149+
) {
150+
let str = "";
151+
152+
for (let i = 0; i < length; i++)
153+
str += chars[this.random_int(0, chars.length)];
154+
155+
return str;
91156
}
92157

93158
/**
@@ -110,16 +175,43 @@ class XOR128 {
110175
* @returns {any} item from input array
111176
*/
112177
random_from_array(arr) {
178+
if (!(arr instanceof Array))
179+
throw new Error("XOR128: parameter must be an array");
180+
113181
return arr[this.random_int(0, arr.length)];
114182
}
115183

116184
/**
117-
* Shuffles the provided array without returning it (the original array gets shuffled)
185+
* Returns a random char from the provided string
186+
*
187+
* @param {string} str a string
188+
* @returns {string} char from input string
189+
*/
190+
random_from_string(str) {
191+
if (typeof str !== "string")
192+
throw new Error("XOR128: parameter must be a string");
193+
194+
return str.charAt(this.random_int(0, str.length));
195+
}
196+
197+
/**
198+
* Returns a random item from the provided array or a random char from the provided string
199+
*
200+
* @returns {any} item from input array or char from input string
201+
*/
202+
pick(x) {
203+
if (x instanceof Array) return this.random_from_array(x);
204+
else if (typeof x === "string") return this.random_from_string(x);
205+
else throw new Error("XOR128: parameter must be an array or a string");
206+
}
207+
208+
/**
209+
* Shuffles the provided array (the original array does not get shuffled)
118210
*
119211
* @param {Array} arr an array
120212
*/
121213
shuffle_array(arr) {
122-
return arr
214+
return [...arr]
123215
.map((s) => ({ sort: this.random(), value: s }))
124216
.sort((a, b) => a.sort - b.sort)
125217
.map((a) => a.value);
@@ -139,4 +231,17 @@ class XOR128 {
139231
.map((a) => a.value)
140232
.join("");
141233
}
234+
235+
/**
236+
* Shuffles and returns an array or a string.
237+
*
238+
* @param {Array|String} x an array or a string
239+
* @returns {any} shuffled array or string
240+
*/
241+
shuffle(x) {
242+
if (x instanceof Array) return this.shuffle_array(x);
243+
if (typeof x === "string") return this.shuffle_string(x);
244+
245+
throw new Error("XOR128: parameter must be an array or a string");
246+
}
142247
}

0 commit comments

Comments
 (0)