25 |
|
|
26 |
|
package java.util; |
27 |
|
|
28 |
+ |
import java.security.SecureRandom; |
29 |
|
import java.util.concurrent.atomic.AtomicLong; |
30 |
|
import java.util.Spliterator; |
31 |
|
import java.util.function.IntConsumer; |
122 |
|
* this generator as nextSplit, and uses mix64(nextSplit) as its |
123 |
|
* own gamma value. Computations of gammas themselves use a fixed |
124 |
|
* constant as the second argument to the addGammaModGeorge |
125 |
< |
* function, GAMMA_GAMMA, a "genuinely random" number from a |
126 |
< |
* radioactive decay reading (obtained from |
127 |
< |
* http://www.fourmilab.ch/hotbits/) meeting the above range |
128 |
< |
* constraint. Using a fixed constant maintains the invariant that |
128 |
< |
* the value of gamma is the same for every instance that is at |
129 |
< |
* the same split-distance from their common root. (Note: there is |
130 |
< |
* nothing especially magic about obtaining this constant from a |
131 |
< |
* "truly random" physical source rather than just choosing one |
132 |
< |
* arbitrarily; using "hotbits" was merely an aesthetically pleasing |
133 |
< |
* choice. In either case, good statistical behavior of the |
134 |
< |
* algorithm should be, and was, verified by using the DieHarder |
135 |
< |
* test suite.) |
125 |
> |
* function, GAMMA_GAMMA. The value of GAMMA_GAMMA is arbitrary |
126 |
> |
* (except must be at least 13), but because it serves as the base |
127 |
> |
* of split sequences, should be subject to validation of |
128 |
> |
* consequent random number quality metrics. |
129 |
|
* |
130 |
|
* The mix64 bit-mixing function called by nextLong and other |
131 |
|
* methods computes the same value as the "64-bit finalizer" |
151 |
|
* SplittableRandom. Unlike other cases, this split must be |
152 |
|
* performed in a thread-safe manner. We use |
153 |
|
* AtomicLong.compareAndSet as the (typically) most efficient |
154 |
< |
* mechanism. To bootstrap, we start off using a function of the |
155 |
< |
* current System time as seed, and update using another |
156 |
< |
* "genuinely random" constant DEFAULT_SEED_GAMMA. The default |
157 |
< |
* constructor uses GAMMA_GAMMA, not 0, for its splitSeed argument |
158 |
< |
* (addGammaModGeorge(0, GAMMA_GAMMA) == GAMMA_GAMMA) to reflect |
159 |
< |
* that each is split from this root generator, even though the |
160 |
< |
* root is not explicitly represented as a SplittableRandom. When |
168 |
< |
* establishing the initial seed, we use both |
169 |
< |
* System.currentTimeMillis and System.nanoTime(), to avoid |
170 |
< |
* regularities that may occur if using either alone. |
154 |
> |
* mechanism. To bootstrap, we start off using a SecureRandom |
155 |
> |
* initial default seed, and update using a fixed |
156 |
> |
* DEFAULT_SEED_GAMMA. The default constructor uses GAMMA_GAMMA, |
157 |
> |
* not 0, for its splitSeed argument (addGammaModGeorge(0, |
158 |
> |
* GAMMA_GAMMA) == GAMMA_GAMMA) to reflect that each is split from |
159 |
> |
* this root generator, even though the root is not explicitly |
160 |
> |
* represented as a SplittableRandom. |
161 |
|
*/ |
162 |
|
|
163 |
|
/** |
164 |
< |
* The "genuinely random" value for producing new gamma values. |
165 |
< |
* The value is arbitrary, subject to the requirement that it be |
166 |
< |
* greater or equal to 13. |
164 |
> |
* The value for producing new gamma values. Must be greater or |
165 |
> |
* equal to 13. Otherwise, the value is arbitrary subject to |
166 |
> |
* validation of the resulting statistical quality of splits. |
167 |
|
*/ |
168 |
|
private static final long GAMMA_GAMMA = 0xF2281E2DBA6606F3L; |
169 |
|
|
170 |
|
/** |
171 |
< |
* The "genuinely random" seed update value for default constructors. |
172 |
< |
* The value is arbitrary, subject to the requirement that it be |
183 |
< |
* greater or equal to 13. |
171 |
> |
* The seed update value for default constructors. Must be |
172 |
> |
* greater or equal to 13. Otherwise, the value is arbitrary. |
173 |
|
*/ |
174 |
|
private static final long DEFAULT_SEED_GAMMA = 0xBD24B73A95FB84D9L; |
175 |
|
|
189 |
|
* The next seed for default constructors. |
190 |
|
*/ |
191 |
|
private static final AtomicLong defaultSeedGenerator = |
192 |
< |
new AtomicLong(mix64(System.currentTimeMillis()) ^ |
204 |
< |
mix64(System.nanoTime())); |
192 |
> |
new AtomicLong(getInitialDefaultSeed()); |
193 |
|
|
194 |
|
/** |
195 |
|
* The seed, updated only via method nextSeed. |
290 |
|
return mix64(newSeed); |
291 |
|
} |
292 |
|
|
293 |
+ |
/** |
294 |
+ |
* Returns an initial default seed. |
295 |
+ |
*/ |
296 |
+ |
private static long getInitialDefaultSeed() { |
297 |
+ |
byte[] seedBytes = java.security.SecureRandom.getSeed(8); |
298 |
+ |
long s = (long)(seedBytes[0]) & 0xffL; |
299 |
+ |
for (int i = 1; i < 8; ++i) |
300 |
+ |
s = (s << 8) | ((long)(seedBytes[i]) & 0xffL); |
301 |
+ |
return s; |
302 |
+ |
} |
303 |
+ |
|
304 |
|
/* |
305 |
|
* Internal versions of nextX methods used by streams, as well as |
306 |
|
* the public nextX(origin, bound) methods. These exist mainly to |