1
1
/**
2
2
* XOR128 js implementation
3
- * @version 1.0 .0
3
+ * @version 1.1 .0
4
4
* @author Lorenzo Rossi - https://www.lorenzoros.si - https://github.com/lorossi/
5
5
* @license MIT
6
6
*/
@@ -12,17 +12,47 @@ class XOR128 {
12
12
* All parameters are optional, if nothing is passed a random value from
13
13
* js functions Math.random() will be used
14
14
*
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
16
17
* @param {number } [y] second seed
17
18
* @param {number } [z] third seed
18
19
* @param {number } [w] fourth seed
19
20
* @returns {XOR128 }
20
21
*/
21
22
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
+ }
26
56
27
57
if (
28
58
typeof x !== "number" ||
@@ -35,6 +65,8 @@ class XOR128 {
35
65
if ( x < 1 || y < 1 || z < 1 || w < 1 )
36
66
throw new Error ( "XOR128: seed values must be greater than 0" ) ;
37
67
68
+ if ( arguments . length > 4 ) throw new Error ( "XOR128: too many arguments" ) ;
69
+
38
70
this . _x = x ;
39
71
this . _y = y ;
40
72
this . _z = z ;
@@ -59,6 +91,12 @@ class XOR128 {
59
91
a = 0 ;
60
92
}
61
93
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
+
62
100
const t = this . _x ^ ( ( this . _x << 11 ) >>> 0 ) ;
63
101
64
102
this . _x = this . _y ;
@@ -87,7 +125,34 @@ class XOR128 {
87
125
a = 0 ;
88
126
}
89
127
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 ;
91
156
}
92
157
93
158
/**
@@ -110,16 +175,43 @@ class XOR128 {
110
175
* @returns {any } item from input array
111
176
*/
112
177
random_from_array ( arr ) {
178
+ if ( ! ( arr instanceof Array ) )
179
+ throw new Error ( "XOR128: parameter must be an array" ) ;
180
+
113
181
return arr [ this . random_int ( 0 , arr . length ) ] ;
114
182
}
115
183
116
184
/**
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)
118
210
*
119
211
* @param {Array } arr an array
120
212
*/
121
213
shuffle_array ( arr ) {
122
- return arr
214
+ return [ ... arr ]
123
215
. map ( ( s ) => ( { sort : this . random ( ) , value : s } ) )
124
216
. sort ( ( a , b ) => a . sort - b . sort )
125
217
. map ( ( a ) => a . value ) ;
@@ -139,4 +231,17 @@ class XOR128 {
139
231
. map ( ( a ) => a . value )
140
232
. join ( "" ) ;
141
233
}
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
+ }
142
247
}
0 commit comments