diff -r effb66aab08b -r da026c172c1e src/java.base/share/classes/java/util/random/RandomGenerator.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/java.base/share/classes/java/util/random/RandomGenerator.java Thu Nov 14 12:50:08 2019 -0400 @@ -0,0 +1,1651 @@ +/* + * Copyright (c) 2016, 2019, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package java.util.random; + +import java.math.BigInteger; +import java.util.Objects; +import java.util.stream.DoubleStream; +import java.util.stream.IntStream; +import java.util.stream.LongStream; +import java.util.stream.Stream; + +/** + * The {@link RandomGenerator} interface is designed to provide a common protocol for objects that + * generate random or (more typically) pseudorandom sequences of numbers (or Boolean values). + * Such a sequence may be obtained by either repeatedly invoking a method that returns a single + * (pseudo)randomly chosen value, or by invoking a method that returns a stream of (pseudo)randomly + * chosen values. + *
+ * Ideally, given an implicitly or explicitly specified range of values, each value would be chosen + * independently and uniformly from that range. In practice, one may have to settle for some + * approximation to independence and uniformity. + *
+ * In the case of {@code int}, {@code long}, and {@link Boolean} values, if there is no explicit + * specification of range, then the range includes all possible values of the type. In the case of + * {@code float} and {@code double} values, a value is always chosen from the set of + * 2w values between 0.0 (inclusive) and 1.0 (exclusive), where w is 23 for + * {@code float} values and 52 for {@code double} values, such that adjacent values differ by + * 2−w; if an explicit range is specified, then the chosen number is + * computationally scaled and translated so as to appear to have been chosen from that range. + *
+ * Each method that returns a stream produces a stream of values each of which is chosen in the same + * manner as for a method that returns a single (pseudo)randomly chosen value. For example, if + * {@code r} implements {@link RandomGenerator}, then the method call {@code r.ints(100)} returns a + * stream of 100 {@code int} values. These are not necessarily the exact same values that would + * have been returned if instead {@code r.nextInt()} had been called 100 times; all that is + * guaranteed is that each value in the stream is chosen in a similar (pseudo)random manner from the + * same range. + *
+ * Every object that implements the {@link RandomNumberGenerator} interface by using a + * pseudorandom algorithm is assumed to contain a finite amount of state. Using such an object to + * generate a pseudorandomly chosen value alters its state by computing a new state as a function + * of the current state, without reference to any information other than the current state. + * The number of distinct possible states of such an object is called its period. + * (Some implementations of the {@link RandomNumberGenerator} interface may be truly random + * rather than pseudorandom, for example relying on the statistical behavior of a physical + * object to derive chosen values. Such implementations do not have a fixed period.) + *
+ * As a rule, objects that implement the {@link RandomGenerator} interface need not be thread-safe. + * It is recommended that multithreaded applications use either {@link ThreadLocalRandom} or + * (preferably) pseudorandom number generators that implement the {@link SplittableGenerator} or + * {@link JumpableGenerator} interface. + *
+ * To implement this interface, a class only needs to provide concrete definitions for the methods + * {@code nextLong()} and {@code period()}. Default implementations are provided for all other + * methods (but it may be desirable to override some of them, especially {@code nextInt()} if the + * underlying algorithm is {@code int}-based). Moreover, it may be preferable instead to implement + * a more specialized interface such as {@link JumpableGenerator} or {@link LeapableGenerator}, + * or to extend an abstract implementation-support class such as {@link AbstractSplittableGenerator} + * or {@link AbstractArbitrarilyJumpableGenerator}. + *
+ * Objects that implement {@link RandomGenerator} are typically not cryptographically secure.
+ * Consider instead using {@link java.security.SecureRandom} to get a cryptographically secure
+ * pseudorandom number generator for use by security-sensitive applications. Note, however, that
+ * {@code java.security.SecureRandom} does implement the {@link RandomGenerator} interface, so that
+ * instances of {@code java.security.SecureRandom} may be used interchangeably with other types of
+ * pseudorandom generators in applications that do not require a secure generator.
+ *
+ * @since 14
+ */
+public interface RandomGenerator {
+
+ /**
+ * Supported random number Algorithms.
+ */
+ public enum Algorithm {
+ /**
+ * L64X128MixRandom algorithm
+ */
+ L64X128MixRandom("L64X128MixRandom"),
+ /**
+ * L64X256MixRandom algorithm
+ */
+ L64X256MixRandom("L64X256MixRandom"),
+ /**
+ * L64X1024MixRandom algorithm
+ */
+ L64X1024MixRandom("L64X1024MixRandom"),
+ /**
+ * L128X256MixRandom algorithm
+ */
+ L128X256MixRandom("L128X256MixRandom"),
+ /**
+ * MRG32k3a algorithm
+ */
+ MRG32k3a("MRG32k3a"),
+ /**
+ * Legacy Random algorithm
+ */
+ @Deprecated
+ Random("Random"),
+ /**
+ * Legacy SecureRandom algorithm
+ */
+ @Deprecated
+ SecureRandom("SecureRandom"),
+ /**
+ * Xoroshiro128StarStar algorithm
+ */
+ Xoroshiro128StarStar("Xoroshiro128StarStar"),
+ /**
+ * Xoshiro256StarStar algorithm
+ */
+ Xoshiro256StarStar("Xoshiro256StarStar");
+
+ private String name;
+
+ private Algorithm(String name) {
+ this.name = name;
+ }
+
+ public String toString() {
+ return name;
+ }
+
+ /**
+ * Returns an instance of {@link RandomGenerator} that utilizes this algorithm.
+ *
+ * @return An instance of {@link RandomGenerator}
+ */
+ public RandomGenerator instance() {
+ return RandomGeneratorFactory.of(name, RandomGenerator.class);
+ }
+
+ /**
+ * Returns a {@link RandomGeneratorFactory} that can produce instances
+ * of {@link RandomGenerator} that utilizes this algorithm.
+ *
+ * @return {@link RandomGeneratorFactory} of {@link RandomGenerator}
+ */
+ public RandomGeneratorFactory
+ * The default implementation tests the high-order bit (sign bit) of a value produced by
+ * {@code nextInt()}, on the grounds that some algorithms for pseudorandom number generation
+ * produce values whose high-order bits have better statistical quality than the low-order bits.
+ *
+ * @return a pseudorandomly chosen {@code boolean} value
+ */
+ default boolean nextBoolean() {
+ return nextInt() < 0;
+ }
+
+ /**
+ * Returns a pseudorandom {@code float} value between zero (inclusive) and one (exclusive).
+ *
+ * The default implementation uses the 24 high-order bits from a call to {@code nextInt()}.
+ *
+ * @return a pseudorandom {@code float} value between zero (inclusive) and one (exclusive)
+ */
+ default float nextFloat() {
+ return (nextInt() >>> 8) * 0x1.0p-24f;
+ }
+
+ /**
+ * Returns a pseudorandomly chosen {@code float} value between zero
+ * (inclusive) and the specified bound (exclusive).
+ *
+ * @param bound the upper bound (exclusive) for the returned value.
+ * Must be positive and finite
+ *
+ * @return a pseudorandomly chosen {@code float} value between
+ * zero (inclusive) and the bound (exclusive)
+ *
+ * @throws IllegalArgumentException if {@code bound} is not
+ * both positive and finite
+ *
+ * @implNote The default implementation simply calls
+ * {@code RandomSupport.checkBound(bound)} and then
+ * {@code RandomSupport.boundedNextFloat(this, bound)}.
+ */
+ default float nextFloat(float bound) {
+ RandomSupport.checkBound(bound);
+ return RandomSupport.boundedNextFloat(this, bound);
+ }
+
+ /**
+ * Returns a pseudorandomly chosen {@code float} value between the
+ * specified origin (inclusive) and the specified bound (exclusive).
+ *
+ * @param origin the least value that can be returned
+ * @param bound the upper bound (exclusive)
+ *
+ * @return a pseudorandomly chosen {@code float} value between the
+ * origin (inclusive) and the bound (exclusive)
+ *
+ * @throws IllegalArgumentException if {@code origin} is not finite,
+ * or {@code bound} is not finite, or {@code origin}
+ * is greater than or equal to {@code bound}
+ *
+ * @implNote The default implementation simply calls
+ * {@code RandomSupport.checkRange(origin, bound)} and then
+ * {@code RandomSupport.boundedNextFloat(this, origin, bound)}.
+ */
+ default float nextFloat(float origin, float bound) {
+ RandomSupport.checkRange(origin, bound);
+ return RandomSupport.boundedNextFloat(this, origin, bound);
+ }
+
+ /**
+ * Returns a pseudorandom {@code double} value between zero (inclusive) and one (exclusive).
+ *
+ * The default implementation uses the 53 high-order bits from a call to {@code nextLong()}.
+ *
+ * @return a pseudorandom {@code double} value between zero (inclusive) and one (exclusive)
+ */
+ default double nextDouble() {
+ return (nextLong() >>> 11) * 0x1.0p-53;
+ }
+
+ /**
+ * Returns a pseudorandomly chosen {@code double} value between zero
+ * (inclusive) and the specified bound (exclusive).
+ *
+ * @param bound the upper bound (exclusive) for the returned value.
+ * Must be positive and finite
+ *
+ * @return a pseudorandomly chosen {@code double} value between
+ * zero (inclusive) and the bound (exclusive)
+ *
+ * @throws IllegalArgumentException if {@code bound} is not
+ * both positive and finite
+ *
+ * @implNote The default implementation simply calls
+ * {@code RandomSupport.checkBound(bound)} and then
+ * {@code RandomSupport.boundedNextDouble(this, bound)}.
+ */
+ default double nextDouble(double bound) {
+ RandomSupport.checkBound(bound);
+ return RandomSupport.boundedNextDouble(this, bound);
+ }
+
+ /**
+ * Returns a pseudorandomly chosen {@code double} value between the
+ * specified origin (inclusive) and the specified bound (exclusive).
+ *
+ * @param origin the least value that can be returned
+ * @param bound the upper bound (exclusive) for the returned value
+ *
+ * @return a pseudorandomly chosen {@code double} value between the
+ * origin (inclusive) and the bound (exclusive)
+ *
+ * @throws IllegalArgumentException if {@code origin} is not finite,
+ * or {@code bound} is not finite, or {@code origin}
+ * is greater than or equal to {@code bound}
+ *
+ * @implNote The default implementation simply calls
+ * {@code RandomSupport.checkRange(origin, bound)} and then
+ * {@code RandomSupport.boundedNextDouble(this, origin, bound)}.
+ */
+ default double nextDouble(double origin, double bound) {
+ RandomSupport.checkRange(origin, bound);
+ return RandomSupport.boundedNextDouble(this, origin, bound);
+ }
+
+ /**
+ * Returns a pseudorandomly chosen {@code int} value.
+ *
+ * The default implementation uses the 32 high-order bits from a call to {@code nextLong()}.
+ *
+ * @return a pseudorandomly chosen {@code int} value
+ */
+ default public int nextInt() {
+ return (int)(nextLong() >>> 32);
+ }
+
+ /**
+ * Returns a pseudorandomly chosen {@code int} value between
+ * zero (inclusive) and the specified bound (exclusive).
+ *
+ * @param bound the upper bound (exclusive) for the returned value. Must be positive.
+ *
+ * @return a pseudorandomly chosen {@code int} value between
+ * zero (inclusive) and the bound (exclusive)
+ *
+ * @throws IllegalArgumentException if {@code bound} is not positive
+ *
+ * @implNote The default implementation simply calls
+ * {@code RandomSupport.checkBound(bound)} and then
+ * {@code RandomSupport.boundedNextInt(this, bound)}.
+ */
+ default int nextInt(int bound) {
+ RandomSupport.checkBound(bound);
+ return RandomSupport.boundedNextInt(this, bound);
+ }
+
+ /**
+ * Returns a pseudorandomly chosen {@code int} value between the
+ * specified origin (inclusive) and the specified bound (exclusive).
+ *
+ * @param origin the least value that can be returned
+ * @param bound the upper bound (exclusive) for the returned value
+ *
+ * @return a pseudorandomly chosen {@code int} value between the
+ * origin (inclusive) and the bound (exclusive)
+ *
+ * @throws IllegalArgumentException if {@code origin} is greater than
+ * or equal to {@code bound}
+ *
+ * @implNote The default implementation simply calls
+ * {@code RandomSupport.checkRange(origin, bound)} and then
+ * {@code RandomSupport.boundedNextInt(this, origin, bound)}.
+ */
+ default int nextInt(int origin, int bound) {
+ RandomSupport.checkRange(origin, bound);
+ return RandomSupport.boundedNextInt(this, origin, bound);
+ }
+
+ /**
+ * Returns a pseudorandomly chosen {@code long} value.
+ *
+ * @return a pseudorandomly chosen {@code long} value
+ */
+ long nextLong();
+
+ /**
+ * Returns a pseudorandomly chosen {@code long} value between
+ * zero (inclusive) and the specified bound (exclusive).
+ *
+ * @param bound the upper bound (exclusive) for the returned value. Must be positive.
+ *
+ * @return a pseudorandomly chosen {@code long} value between
+ * zero (inclusive) and the bound (exclusive)
+ *
+ * @throws IllegalArgumentException if {@code bound} is not positive
+ *
+ * @implNote The default implementation simply calls
+ * {@code RandomSupport.checkBound(bound)} and then
+ * {@code RandomSupport.boundedNextLong(this, bound)}.
+ */
+ default long nextLong(long bound) {
+ RandomSupport.checkBound(bound);
+ return RandomSupport.boundedNextLong(this, bound);
+ }
+
+ /**
+ * Returns a pseudorandomly chosen {@code long} value between the
+ * specified origin (inclusive) and the specified bound (exclusive).
+ *
+ * @param origin the least value that can be returned
+ * @param bound the upper bound (exclusive) for the returned value
+ *
+ * @return a pseudorandomly chosen {@code long} value between the
+ * origin (inclusive) and the bound (exclusive)
+ *
+ * @throws IllegalArgumentException if {@code origin} is greater than
+ * or equal to {@code bound}
+ *
+ * @implNote The default implementation simply calls
+ * {@code RandomSupport.checkRange(origin, bound)} and then
+ * {@code RandomSupport.boundedNextInt(this, origin, bound)}.
+ *
+ */
+ default long nextLong(long origin, long bound) {
+ RandomSupport.checkRange(origin, bound);
+ return RandomSupport.boundedNextLong(this, origin, bound);
+ }
+
+ /**
+ * Returns a {@code double} value pseudorandomly chosen from
+ * a Gaussian (normal) distribution whose mean is 0 and whose
+ * standard deviation is 1.
+ *
+ * @return a {@code double} value pseudorandomly chosen from a
+ * Gaussian distribution
+ */
+ default double nextGaussian() {
+ return RandomSupport.computeNextGaussian(this);
+ }
+
+ /**
+ * Returns a {@code double} value pseudorandomly chosen from
+ * a Gaussian (normal) distribution with a mean and
+ * standard deviation specified by the arguments.
+ *
+ * @param mean the mean of the Gaussian distribution to be drawn from
+ * @param stddev the standard deviation (square root of the variance)
+ * of the Gaussian distribution to be drawn from
+ *
+ * @return a {@code double} value pseudorandomly chosen from the
+ * specified Gaussian distribution
+ *
+ * @throws IllegalArgumentException if {@code stddev} is negative
+ */
+ default double nextGaussian(double mean, double stddev) {
+ if (stddev < 0.0) throw new IllegalArgumentException("standard deviation must be non-negative");
+ return mean + stddev * RandomSupport.computeNextGaussian(this);
+ }
+
+ /**
+ * Returns a nonnegative {@code double} value pseudorandomly chosen
+ * from an exponential distribution whose mean is 1.
+ *
+ * @return a nonnegative {@code double} value pseudorandomly chosen from an
+ * exponential distribution
+ */
+ default double nextExponential() {
+ return RandomSupport.computeNextExponential(this);
+ }
+
+ /**
+ * Returns the period of this {@link RandomGenerator} object.
+ *
+ * @return a {@link BigInteger} whose value is the number of distinct possible states of this
+ * {@link RandomGenerator} object, or 0 if unknown, or negative if extremely
+ * large.
+ */
+ BigInteger period();
+
+ /**
+ * The value (0) returned by the {@code period()} method if the period is unknown.
+ */
+ static final BigInteger UNKNOWN_PERIOD = BigInteger.ZERO;
+
+ /**
+ * The (negative) value returned by the {@code period()} method if this generator
+ * has no period because it is truly random rather than just pseudorandom.
+ */
+ static final BigInteger TRULY_RANDOM = BigInteger.valueOf(-1);
+
+ /**
+ * The (negative) value that may be returned by the {@code period()} method
+ * if this generator has a huge period (larger than 2**(2**16)).
+ */
+ static final BigInteger HUGE_PERIOD = BigInteger.valueOf(-2);
+
+ /**
+ * The {@link StreamableGenerator} interface augments the {@link RandomGenerator} interface
+ * to provide methods that return streams of {@link RandomGenerator} objects.
+ * Ideally, such a stream of objects would have the property that the
+ * behavior of each object is statistically independent of all the others.
+ * In practice, one may have to settle for some approximation to this property.
+ *
+ * A generator that implements interface {@link SplittableGenerator}
+ * may choose to use its {@code splits} method to implement the {@code rngs}
+ * method required by this interface.
+ *
+ * A generator that implements interface {@link JumpableGenerator}
+ * may choose to use its {@code jumps} method to implement the {@code rngs}
+ * method required by this interface.
+ *
+ * A generator that implements interface {@link LeapableGenerator}
+ * may choose to use its {@code leaps} method to implement the {@code rngs}
+ * method required by this interface.
+ *
+ * An implementation of the {@link StreamableGenerator} interface must provide
+ * concrete definitions for the methods {@code nextInt()}, {@code nextLong},
+ * {@code period()}, and {@code rngs()}.
+ * Default implementations are provided for all other methods.
+ *
+ * Objects that implement {@link StreamableGenerator} are typically
+ * not cryptographically secure. Consider instead using
+ * {@link java.security.SecureRandom} to get a cryptographically
+ * secure pseudo-random number generator for use by
+ * security-sensitive applications.
+ *
+ * @since 14
+ */
+ public interface StreamableGenerator extends RandomGenerator {
+
+ /**
+ * Returns an instance of {@link StreamableGenerator} that utilizes the
+ * {@code name} algorithm.
+ *
+ * @param name Name of random number generator algorithm
+ *
+ * @return An instance of {@link StreamableGenerator}
+ */
+ public static StreamableGenerator of(String name) {
+ Objects.requireNonNull(name);
+ return RandomGeneratorFactory.of(name, StreamableGenerator.class);
+ }
+
+ /**
+ * Returns an instance of {@link StreamableGenerator} that utilizes the
+ * specified {@code algorithm}.
+ *
+ * @param algorithm Random number generator algorithm
+ *
+ * @return An instance of {@link StreamableGenerator}
+ */
+ public static StreamableGenerator of(Algorithm algorithm) {
+ Objects.requireNonNull(algorithm);
+ return RandomGeneratorFactory.of(algorithm.toString(), StreamableGenerator.class);
+ }
+
+ /**
+ * Returns a {@link RandomGeneratorFactory} that can produce instances
+ * of {@link StreamableGenerator} that utilizes the {@code name} algorithm.
+ *
+ * @param name Name of random number generator algorithm
+ *
+ * @return {@link RandomGeneratorFactory} of {@link StreamableGenerator}
+ */
+ public static RandomGeneratorFactory
+ * Ideally, all {@link SplittableGenerator} objects produced by recursive
+ * splitting from a single original {@link SplittableGenerator} object are
+ * statistically independent of one another and individually uniform.
+ * Therefore we would expect the set of values collectively generated
+ * by a set of such objects to have the same statistical properties as
+ * if the same quantity of values were generated by a single thread
+ * using a single {@link SplittableGenerator} object. In practice, one must
+ * settle for some approximation to independence and uniformity.
+ *
+ * Methods are provided to perform a single splitting operation and
+ * also to produce a stream of generators split off from the original
+ * (by either iterative or recursive splitting, or a combination).
+ *
+ * An implementation of the {@link SplittableGenerator} interface must provide
+ * concrete definitions for the methods {@code nextInt()}, {@code nextLong},
+ * {@code period()}, {@code split()}, {@code split(SplittableGenerator)},
+ * {@code splits()}, {@code splits(long)}, {@code splits(SplittableGenerator)},
+ * and {@code splits(long, SplittableGenerator)}. Perhaps the most convenient
+ * way to implement this interface is to extend the abstract class
+ * {@link AbstractSplittableGenerator}.
+ *
+ * Objects that implement {@link SplittableGenerator} are
+ * typically not cryptographically secure. Consider instead using
+ * {@link java.security.SecureRandom} to get a cryptographically
+ * secure pseudo-random number generator for use by
+ * security-sensitive applications.
+ *
+ * @since 14
+ */
+ public interface SplittableGenerator extends StreamableGenerator {
+
+ /**
+ * Returns an instance of {@link SplittableGenerator} that utilizes the
+ * {@code name} algorithm.
+ *
+ * @param name Name of random number generator algorithm
+ *
+ * @return An instance of {@link SplittableGenerator}
+ */
+ public static SplittableGenerator of(String name) {
+ Objects.requireNonNull(name);
+ return RandomGeneratorFactory.of(name, SplittableGenerator.class);
+ }
+
+ /**
+ * Returns an instance of {@link SplittableGenerator} that utilizes the
+ * specified {@code algorithm}.
+ *
+ * @param algorithm Random number generator algorithm
+ *
+ * @return An instance of {@link SplittableGenerator}
+ */
+ public static SplittableGenerator of(Algorithm algorithm) {
+ Objects.requireNonNull(algorithm);
+ return RandomGeneratorFactory.of(algorithm.toString(), SplittableGenerator.class);
+ }
+
+ /**
+ * Returns a {@link RandomGeneratorFactory} that can produce instances
+ * of {@link SplittableGenerator} that utilizes the {@code name} algorithm.
+ *
+ * @param name Name of random number generator algorithm
+ *
+ * @return {@link RandomGeneratorFactory} of {@link SplittableGenerator}
+ */
+ public static RandomGeneratorFactory
+ * Ideally, all {@link JumpableGenerator} objects produced by iterative jumping from a single
+ * original {@link JumpableGenerator} object are statistically independent of one another and
+ * individually uniform. In practice, one must settle for some approximation to independence and
+ * uniformity. In particular, a specific implementation may assume that each generator in a
+ * stream produced by the {@code jumps} method is used to produce a number of values no larger
+ * than either 264 or the square root of its period. Implementors are advised to use
+ * algorithms whose period is at least 2127.
+ *
+ * Methods are provided to perform a single jump operation and also to produce a stream of
+ * generators produced from the original by iterative copying and jumping of internal state. A
+ * typical strategy for a multithreaded application is to create a single {@link
+ * JumpableGenerator} object, calls its {@code jumps} method exactly once, and then parcel out
+ * generators from the resulting stream, one to each thread. It is generally not a good idea to
+ * call {@code jump} on a generator that was itself produced by the {@code jumps} method,
+ * because the result may be a generator identical to another generator already produce by that
+ * call to the {@code jumps} method. For this reason, the return type of the {@code jumps}
+ * method is {@code Stream
+ * An implementation of the {@link JumpableGenerator} interface must provide concrete
+ * definitions for the methods {@code nextInt()}, {@code nextLong}, {@code period()}, {@code
+ * copy()}, {@code jump()}, and {@code defaultJumpDistance()}. Default implementations are
+ * provided for all other methods.
+ *
+ * Objects that implement {@link JumpableGenerator} are typically not cryptographically secure.
+ * Consider instead using {@link java.security.SecureRandom} to get a cryptographically secure
+ * pseudo-random number generator for use by security-sensitive applications.
+ *
+ * @since 14
+ */
+ public interface JumpableGenerator extends StreamableGenerator {
+
+ /**
+ * Returns an instance of {@link JumpableGenerator} that utilizes the
+ * {@code name} algorithm.
+ *
+ * @param name Name of random number generator algorithm
+ *
+ * @return An instance of {@link JumpableGenerator}
+ */
+ public static JumpableGenerator of(String name) {
+ Objects.requireNonNull(name);
+ return RandomGeneratorFactory.of(name, JumpableGenerator.class);
+ }
+
+ /**
+ * Returns an instance of {@link JumpableGenerator} that utilizes the
+ * specified {@code algorithm}.
+ *
+ * @param algorithm Random number generator algorithm
+ *
+ * @return An instance of {@link JumpableGenerator}
+ */
+ public static JumpableGenerator of(Algorithm algorithm) {
+ Objects.requireNonNull(algorithm);
+ return RandomGeneratorFactory.of(algorithm.toString(), JumpableGenerator.class);
+ }
+
+ /**
+ * Returns a {@link RandomGeneratorFactory} that can produce instances
+ * of {@link JumpableGenerator} that utilizes the {@code name} algorithm.
+ *
+ * @param name Name of random number generator algorithm
+ *
+ * @return {@link RandomGeneratorFactory} of {@link JumpableGenerator}
+ */
+ public static RandomGeneratorFactory
+ * Typically one will construct a series of {@link LeapableGenerator} objects by iterative
+ * leaping from a single original {@link LeapableGenerator} object, and then for each such
+ * object produce a subseries of objects by iterative jumping. There is little conceptual
+ * difference between leaping and jumping, but typically a leap will be a very long jump in the
+ * state cycle (perhaps distance 2128 or so).
+ *
+ * Ideally, all {@link LeapableGenerator} objects produced by iterative leaping and jumping from
+ * a single original {@link LeapableGenerator} object are statistically independent of one
+ * another and individually uniform. In practice, one must settle for some approximation to
+ * independence and uniformity. In particular, a specific implementation may assume that each
+ * generator in a stream produced by the {@code leaps} method is used to produce (by jumping) a
+ * number of objects no larger than 264. Implementors are advised to use algorithms
+ * whose period is at least 2191.
+ *
+ * Methods are provided to perform a single leap operation and also to produce a stream of
+ * generators produced from the original by iterative copying and leaping of internal state.
+ * The generators produced must implement the {@link JumpableGenerator} interface but need not
+ * also implement the {@link LeapableGenerator} interface. A typical strategy for a
+ * multithreaded application is to create a single {@link LeapableGenerator} object, calls its
+ * {@code leaps} method exactly once, and then parcel out generators from the resulting stream,
+ * one to each thread. Then the {@code jumps} method of each such generator be called to
+ * produce a substream of generator objects.
+ *
+ * An implementation of the {@link LeapableGenerator} interface must provide concrete
+ * definitions for the methods {@code nextInt()}, {@code nextLong}, {@code period()},
+ * {@code copy()}, {@code jump()}, {@code defaultJumpDistance()}, {@code leap()},
+ * and {@code defaultLeapDistance()}. Default implementations are provided for all other
+ * methods.
+ *
+ * Objects that implement {@link LeapableGenerator} are typically not cryptographically secure.
+ * Consider instead using {@link java.security.SecureRandom} to get a cryptographically secure
+ * pseudo-random number generator for use by security-sensitive applications.
+ *
+ * @since 14
+ */
+ public interface LeapableGenerator extends JumpableGenerator {
+
+ /**
+ * Returns an instance of {@link LeapableGenerator} that utilizes the
+ * {@code name} algorithm.
+ *
+ * @param name Name of random number generator algorithm
+ *
+ * @return An instance of {@link LeapableGenerator}
+ */
+ public static LeapableGenerator of(String name) {
+ Objects.requireNonNull(name);
+ return RandomGeneratorFactory.of(name, LeapableGenerator.class);
+ }
+
+ /**
+ * Returns an instance of {@link LeapableGenerator} that utilizes the
+ * specified {@code algorithm}.
+ *
+ * @param algorithm Random number generator algorithm
+ *
+ * @return An instance of {@link LeapableGenerator}
+ */
+ public static LeapableGenerator of(Algorithm algorithm) {
+ Objects.requireNonNull(algorithm);
+ return RandomGeneratorFactory.of(algorithm.toString(), LeapableGenerator.class);
+ }
+
+ /**
+ * Returns a {@link RandomGeneratorFactory} that can produce instances
+ * of {@link LeapableGenerator} that utilizes the {@code name} algorithm.
+ *
+ * @param name Name of random number generator algorithm
+ *
+ * @return {@link RandomGeneratorFactory} of {@link LeapableGenerator}
+ */
+ public static RandomGeneratorFactory
+ * Ideally, all {@link ArbitrarilyJumpableGenerator} objects produced by iterative jumping from
+ * a single original {@link ArbitrarilyJumpableGenerator} object are statistically independent
+ * of one another and individually uniform, provided that they do not traverse overlapping
+ * portions of the state cycle. In practice, one must settle for some approximation to
+ * independence and uniformity. In particular, a specific implementation may assume that each
+ * generator in a stream produced by the {@code jumps} method is used to produce a number of
+ * values no larger than the jump distance specified. Implementors are advised to use
+ * algorithms whose period is at least 2127.
+ *
+ * For many applications, it suffices to jump forward by a power of two or some small multiple
+ * of a power of two, but this power of two may not be representable as a {@code long} value.
+ * To avoid the use of {@link java.math.BigInteger} values as jump distances, {@code double}
+ * values are used instead.
+ *
+ * Methods are provided to perform a single jump operation and also to produce a stream of
+ * generators produced from the original by iterative copying and jumping of internal state. A
+ * typical strategy for a multithreaded application is to create a single
+ * {@link ArbitrarilyJumpableGenerator} object, call its {@code jumps} method exactly once, and
+ * then parcel out generators from the resulting stream, one to each thread. However, each
+ * generator produced also has type {@link ArbitrarilyJumpableGenerator}; with care, different
+ * jump distances can be used to traverse the entire state cycle in various ways.
+ *
+ * An implementation of the {@link ArbitrarilyJumpableGenerator} interface must provide concrete
+ * definitions for the methods {@code nextInt()}, {@code nextLong}, {@code period()},
+ * {@code copy()}, {@code jump(double)}, {@code defaultJumpDistance()}, and
+ * {@code defaultLeapDistance()}. Default implementations are provided for all other methods.
+ * Perhaps the most convenient way to implement this interface is to extend the abstract class
+ * {@link ArbitrarilyJumpableGenerator}, which provides spliterator-based implementations of the
+ * methods {@code ints}, {@code longs}, {@code doubles}, {@code rngs}, {@code jumps}, and
+ * {@code leaps}.
+ *
+ * Objects that implement {@link ArbitrarilyJumpableGenerator} are typically not
+ * cryptographically secure. Consider instead using {@link java.security.SecureRandom} to get a
+ * cryptographically secure pseudo-random number generator for use by security-sensitive
+ * applications.
+ *
+ * @since 14
+ */
+ public interface ArbitrarilyJumpableGenerator extends LeapableGenerator {
+
+ /**
+ * Returns an instance of {@link ArbitrarilyJumpableGenerator} that utilizes the
+ * {@code name} algorithm.
+ *
+ * @param name Name of random number generator algorithm
+ *
+ * @return An instance of {@link ArbitrarilyJumpableGenerator}
+ */
+ public static ArbitrarilyJumpableGenerator of(String name) {
+ Objects.requireNonNull(name);
+ return RandomGeneratorFactory.of(name, ArbitrarilyJumpableGenerator.class);
+ }
+
+ /**
+ * Returns an instance of {@link ArbitrarilyJumpableGenerator} that utilizes the
+ * specified {@code algorithm}.
+ *
+ * @param algorithm Random number generator algorithm
+ *
+ * @return An instance of {@link ArbitrarilyJumpableGenerator}
+ */
+ public static ArbitrarilyJumpableGenerator of(Algorithm algorithm) {
+ Objects.requireNonNull(algorithm);
+ return RandomGeneratorFactory.of(algorithm.toString(), ArbitrarilyJumpableGenerator.class);
+ }
+
+ /**
+ * Returns a {@link RandomGeneratorFactory} that can produce instances
+ * of {@link ArbitrarilyJumpableGenerator} that utilizes the {@code name} algorithm.
+ *
+ * @param name Name of random number generator algorithm
+ *
+ * @return {@link RandomGeneratorFactory} of {@link ArbitrarilyJumpableGenerator}
+ */
+ public static RandomGeneratorFactory