Class BaseRandom

    • Constructor Summary

      Constructors 
      Modifier Constructor Description
      protected BaseRandom​(byte[] seed)
      Creates a new RNG with the provided seed.
      protected BaseRandom​(int seedSizeBytes)
      Seed the RNG using the DefaultSeedGenerator to create a seed of the specified size.
      protected BaseRandom​(long seed)
      Creates a new RNG with the provided seed.
      protected BaseRandom​(SeedGenerator randomSeeder, int seedLength)
      Creates a new RNG and seeds it using the provided seed generation strategy.
    • Method Summary

      All Methods Static Methods Instance Methods Abstract Methods Concrete Methods Deprecated Methods 
      Modifier and Type Method Description
      protected abstract MoreObjects.ToStringHelper addSubclassFields​(MoreObjects.ToStringHelper original)
      Adds the fields that were not inherited from BaseRandom to the given MoreObjects.ToStringHelper for dumping.
      protected static byte[] checkLength​(byte[] seed, int requiredLength)
      Checks that the given seed is the expected length, then returns it.
      protected void creditEntropyForNewSeed​(int seedLength)
      Updates the entropy count to reflect a reseeding.
      protected void debitEntropy​(long bits)
      Record that entropy has been spent, and schedule a reseeding if this PRNG has now spent as much as it's been seeded with.
      java8.util.stream.DoubleStream doubles()
      Returns a stream producing an effectively unlimited number of pseudorandom doubles, each between 0.0 (inclusive) and 1.0 (exclusive).
      java8.util.stream.DoubleStream doubles​(double randomNumberOrigin, double randomNumberBound)
      Returns a stream producing an effectively unlimited number of pseudorandom doubles, each conforming to the given origin (inclusive) and bound (exclusive).
      java8.util.stream.DoubleStream doubles​(long streamSize)  
      java8.util.stream.DoubleStream doubles​(long streamSize, double randomNumberOrigin, double randomNumberBound)
      Returns a stream producing the given number of pseudorandom doubles, each conforming to the given origin (inclusive) and bound (exclusive).
      String dump()
      Returns a String representing the state of this object for debugging purposes, including mutable state that Object.toString() usually doesn't return.
      protected static int entropyOfInt​(int origin, int bound)
      Calculates the entropy in bits, rounded up, of a random int between origin (inclusive) and bound (exclusive).
      protected static int entropyOfLong​(long origin, long bound)
      Calculates the entropy in bits, rounded up, of a random long between origin (inclusive) and bound (exclusive).
      protected void fallbackSetSeedIfInitialized()
      Generates and sets a seed using the DefaultSeedGenerator.
      java8.util.stream.DoubleStream gaussians()
      Returns a stream producing an effectively unlimited number of pseudorandom doubles that are normally distributed with mean 0.0 and standard deviation 1.0.
      java8.util.stream.DoubleStream gaussians​(long streamSize)
      Returns a stream producing the given number of pseudorandom doubles that are normally distributed with mean 0.0 and standard deviation 1.0.
      long getEntropyBits()
      Returns an estimate of the current amount of entropy.
      abstract int getNewSeedLength()
      Returns the preferred length of a new byte-array seed.
      SimpleRandomSeeder getRandomSeeder()
      Returns the current seed generator for this PRNG.
      byte[] getSeed()
      Returns the seed.
      protected void initTransientFields()
      Called in constructor and readObject to initialize transient fields.
      protected double internalNextGaussian​(java8.util.function.DoubleSupplier nextDouble)
      Core of a reimplementation of nextGaussian() whose locking is overridable and doesn't happen when a value is already stored.
      java8.util.stream.IntStream ints()  
      java8.util.stream.IntStream ints​(int randomNumberOrigin, int randomNumberBound)
      Returns a stream producing an effectively unlimited number of pseudorandom ints, each conforming to the given origin (inclusive) and bound (exclusive).
      java8.util.stream.IntStream ints​(long streamSize)  
      java8.util.stream.IntStream ints​(long streamSize, int randomNumberOrigin, int randomNumberBound)
      Returns a stream producing the given number of pseudorandom ints, each conforming to the given origin (inclusive) and bound (exclusive).
      protected void lockForNextGaussian()
      Performs whatever locking is needed by nextGaussian().
      java8.util.stream.LongStream longs()
      java8.util.stream.LongStream longs​(long streamSize)  
      java8.util.stream.LongStream longs​(long randomNumberOrigin, long randomNumberBound)
      Returns a stream producing an effectively unlimited number of pseudorandom longs, each conforming to the given origin (inclusive) and bound (exclusive).
      java8.util.stream.LongStream longs​(long streamSize, long randomNumberOrigin, long randomNumberBound)
      Returns a stream producing the given number of pseudorandom longs, each conforming to the given origin (inclusive) and bound (exclusive).
      boolean needsReseedingEarly()
      If true, this PRNG needs reseeding even though its entropy is positive.
      protected abstract int next​(int bits)
      Generates the next pseudorandom number.
      boolean nextBoolean()  
      void nextBytes​(byte[] bytes)
      Generates random bytes and places them into a user-supplied byte array.
      double nextDouble()  
      double nextDouble​(double bound)
      Returns a pseudorandom double value between 0.0 (inclusive) and the specified bound (exclusive).
      double nextDouble​(double origin, double bound)
      Returns a pseudorandom double value between the specified origin (inclusive) and bound (exclusive).
      protected double nextDoubleNoEntropyDebit()
      Returns the next random double between 0.0 (inclusive) and 1.0 (exclusive), but does not debit entropy.
      <E> E nextElement​(E[] array)
      Chooses a random element from the given array.
      <E> E nextElement​(List<E> list)
      Chooses a random element from the given list.
      <E extends Enum<E>>
      E
      nextEnum​(Class<E> enumClass)
      Chooses a random value of the given enum class.
      float nextFloat()  
      double nextGaussian()
      Returns the next pseudorandom, Gaussian ("normally") distributed double value with mean 0.0 and standard deviation 1.0 from this random number generator's sequence.
      int nextInt()  
      int nextInt​(int bound)  
      int nextInt​(int origin, int bound)
      Returns a pseudorandom int value between the specified origin (inclusive) and the specified bound (exclusive).
      long nextLong()
      Returns the next pseudorandom, uniformly distributed long value from this random number generator's sequence.
      long nextLong​(long bound)
      Returns a pseudorandom long value between zero (inclusive) and the specified bound (exclusive).
      long nextLong​(long origin, long bound)
      Returns a pseudorandom long value between the specified origin (inclusive) and the specified bound (exclusive).
      protected long nextLongNoEntropyDebit()
      Returns the next random long, but does not debit entropy.
      boolean preferSeedWithLong()
      Indicates whether Random.setSeed(long) is recommended over ByteArrayReseedableRandom.setSeed(byte[]) when the seed is already in the form of a long.
      void setRandomSeeder​(SimpleRandomSeeder randomSeeder)
      Registers this PRNG with the SimpleRandomSeeder for the corresponding SeedGenerator, to schedule reseeding when we run out of entropy.
      void setSeed​(byte[] seed)
      Reseed this PRNG.
      void setSeed​(long seed)
      Deprecated.
      Some implementations are very slow.
      protected void setSeedInternal​(byte[] seed)
      Sets the seed, and should be overridden to set other state that derives from the seed.
      protected boolean supportsMultipleSeedLengths()
      If true, the subclass takes responsibility for checking whether the seed is non-null and has a valid length, and should throw an IllegalArgumentException in setSeedInternal(byte[]) if not.
      protected void unlockForNextGaussian()
      Releases the locks acquired by lockForNextGaussian().
      boolean usesParallelStreams()  
      boolean withProbability​(double probability)
      Returns true with the given probability, and records that only 1 bit of entropy is being spent.
      protected boolean withProbabilityInternal​(double probability)
      Called by withProbability(double) to generate a boolean with a specified probability of returning true, after checking that probability is strictly between 0 and 1.
    • Field Detail

      • randomSeeder

        protected final AtomicReference<SimpleRandomSeeder> randomSeeder
        If the referent is non-null, it will be invoked to reseed this PRNG whenever random output is taken and getEntropyBits() called immediately afterward would return zero or negative.
      • lock

        protected final ReentrantLock lock
        Lock to prevent concurrent modification of the RNG's internal state.
      • seed

        protected volatile byte[] seed
        The seed this PRNG was seeded with, as a byte array. Used by getSeed() even if the actual internal state of the PRNG is stored elsewhere (since otherwise getSeed() would require a slow type conversion).
      • superConstructorFinished

        protected transient boolean superConstructorFinished
        Set by the constructor once either Random() or Random(long) has returned. Intended for setSeed(long), which may have to ignore calls while this is false if the subclass does not support 8-byte seeds, or it overriddes setSeed(long) to use subclass fields.
    • Constructor Detail

      • BaseRandom

        protected BaseRandom​(SeedGenerator randomSeeder,
                             int seedLength)
                      throws SeedException
        Creates a new RNG and seeds it using the provided seed generation strategy.
        Parameters:
        randomSeeder - The seed generation strategy that will provide the seed value for this RNG.
        seedLength - The seed length in bytes.
        Throws:
        SeedException - If there is a problem generating a seed.
      • BaseRandom

        protected BaseRandom​(byte[] seed)
        Creates a new RNG with the provided seed.
        Parameters:
        seed - the seed.
      • BaseRandom

        protected BaseRandom​(long seed)
        Creates a new RNG with the provided seed. Only works in subclasses that can accept an 8-byte or shorter seed.
        Parameters:
        seed - the seed.
    • Method Detail

      • entropyOfInt

        protected static int entropyOfInt​(int origin,
                                          int bound)
        Calculates the entropy in bits, rounded up, of a random int between origin (inclusive) and bound (exclusive).
        Parameters:
        origin - the minimum, inclusive.
        bound - the maximum, exclusive.
        Returns:
        the entropy.
      • entropyOfLong

        protected static int entropyOfLong​(long origin,
                                           long bound)
        Calculates the entropy in bits, rounded up, of a random long between origin (inclusive) and bound (exclusive).
        Parameters:
        origin - the minimum, inclusive.
        bound - the maximum, exclusive.
        Returns:
        the entropy.
      • usesParallelStreams

        public boolean usesParallelStreams()
        Returns:
        true if this PRNG creates parallel streams; false otherwise.
      • withProbability

        public boolean withProbability​(double probability)

        Returns true with the given probability, and records that only 1 bit of entropy is being spent.

        When probability <= 0, instantly returns false without recording any entropy spent. Likewise, instantly returns true when probability >= 1.

        Parameters:
        probability - The probability of returning true.
        Returns:
        True with probability equal to the probability parameter; false otherwise.
      • withProbabilityInternal

        protected boolean withProbabilityInternal​(double probability)
        Called by withProbability(double) to generate a boolean with a specified probability of returning true, after checking that probability is strictly between 0 and 1.
        Parameters:
        probability - The probability (between 0 and 1 exclusive) of returning true.
        Returns:
        True with probability equal to the probability parameter; false otherwise.
      • nextElement

        public <E> E nextElement​(E[] array)
        Chooses a random element from the given array.
        Type Parameters:
        E - The element type of array; usually inferred by the compiler.
        Parameters:
        array - A non-empty array to choose from.
        Returns:
        An element chosen from array at random, with all elements having equal probability.
      • nextElement

        public <E> E nextElement​(List<E> list)
        Chooses a random element from the given list.
        Type Parameters:
        E - The element type of list; usually inferred by the compiler.
        Parameters:
        list - A non-empty List to choose from.
        Returns:
        An element chosen from list at random, with all elements having equal probability.
      • nextEnum

        public <E extends Enum<E>> E nextEnum​(Class<E> enumClass)
        Chooses a random value of the given enum class.
        Type Parameters:
        E - The type of enumClass; usually inferred by the compiler.
        Parameters:
        enumClass - An enum class having at least one value.
        Returns:
        A value of enumClass chosen at random, with all elements having equal probability.
      • next

        protected abstract int next​(int bits)
        Generates the next pseudorandom number. Called by all other random-number-generating methods. Should not debit the entropy count, since that's done by the calling methods according to the amount they actually output (see for example withProbability(double), which uses 53 random bits but outputs only one, and thus debits only 1 bit of entropy).
        Overrides:
        next in class Random
      • nextBytes

        public void nextBytes​(byte[] bytes)
        Generates random bytes and places them into a user-supplied byte array. The number of random bytes produced is equal to the length of the byte array. Reimplemented for entropy-counting purposes.
        Specified by:
        nextBytes in interface Java8CompatRandom
        Overrides:
        nextBytes in class Random
      • nextLong

        public long nextLong()
        Returns the next pseudorandom, uniformly distributed long value from this random number generator's sequence. Unlike the inherited implementation in Random.nextLong(), ones in BetterRandom generally can be expected to return all 264 possible values.
        Specified by:
        nextLong in interface Java8CompatRandom
        Overrides:
        nextLong in class Random
      • nextLong

        public long nextLong​(long bound)
        Returns a pseudorandom long value between zero (inclusive) and the specified bound (exclusive).
        Parameters:
        bound - the upper bound (exclusive). Must be positive.
        Returns:
        a pseudorandom long value between zero (inclusive) and the bound (exclusive)
        Throws:
        IllegalArgumentException - if bound is not positive
      • nextDouble

        public double nextDouble​(double bound)
        Returns a pseudorandom double value between 0.0 (inclusive) and the specified bound (exclusive).
        Parameters:
        bound - the upper bound (exclusive). Must be positive.
        Returns:
        a pseudorandom double value between zero (inclusive) and the bound (exclusive)
        Throws:
        IllegalArgumentException - if bound is not positive
      • nextDouble

        public double nextDouble​(double origin,
                                 double bound)
        Returns a pseudorandom double value between the specified origin (inclusive) and bound (exclusive).
        Parameters:
        origin - the least value returned
        bound - the upper bound (exclusive)
        Returns:
        a pseudorandom double value between the origin (inclusive) and the bound (exclusive)
        Throws:
        IllegalArgumentException - if origin is greater than or equal to bound
      • doubles

        public java8.util.stream.DoubleStream doubles​(double randomNumberOrigin,
                                                      double randomNumberBound)

        Returns a stream producing an effectively unlimited number of pseudorandom doubles, each conforming to the given origin (inclusive) and bound (exclusive). This implementation uses nextDouble(double, double) to generate these numbers.

        Specified by:
        doubles in interface Java8CompatRandom
      • doubles

        public java8.util.stream.DoubleStream doubles()

        Returns a stream producing an effectively unlimited number of pseudorandom doubles, each between 0.0 (inclusive) and 1.0 (exclusive). This implementation uses nextDouble() to generate these numbers.

        Specified by:
        doubles in interface Java8CompatRandom
      • doubles

        public java8.util.stream.DoubleStream doubles​(long streamSize)
        Specified by:
        doubles in interface Java8CompatRandom
      • doubles

        public java8.util.stream.DoubleStream doubles​(long streamSize,
                                                      double randomNumberOrigin,
                                                      double randomNumberBound)
        Returns a stream producing the given number of pseudorandom doubles, each conforming to the given origin (inclusive) and bound (exclusive). This implementation uses nextDouble(double, double) to generate these numbers.
        Specified by:
        doubles in interface Java8CompatRandom
      • gaussians

        public java8.util.stream.DoubleStream gaussians()

        Returns a stream producing an effectively unlimited number of pseudorandom doubles that are normally distributed with mean 0.0 and standard deviation 1.0. This implementation uses nextGaussian().

        Returns:
        a stream of normally-distributed random doubles.
      • gaussians

        public java8.util.stream.DoubleStream gaussians​(long streamSize)
        Returns a stream producing the given number of pseudorandom doubles that are normally distributed with mean 0.0 and standard deviation 1.0. This implementation uses nextGaussian().
        Parameters:
        streamSize - the number of doubles to generate.
        Returns:
        a stream of streamSize normally-distributed random doubles.
      • nextDoubleNoEntropyDebit

        protected double nextDoubleNoEntropyDebit()
        Returns the next random double between 0.0 (inclusive) and 1.0 (exclusive), but does not debit entropy.
        Returns:
        a pseudorandom double.
      • nextGaussian

        public double nextGaussian()
        Returns the next pseudorandom, Gaussian ("normally") distributed double value with mean 0.0 and standard deviation 1.0 from this random number generator's sequence. Unlike the one in Random, this implementation is lockless.
        Specified by:
        nextGaussian in interface Java8CompatRandom
        Overrides:
        nextGaussian in class Random
      • internalNextGaussian

        protected double internalNextGaussian​(java8.util.function.DoubleSupplier nextDouble)
        Core of a reimplementation of nextGaussian() whose locking is overridable and doesn't happen when a value is already stored.
        Parameters:
        nextDouble - shall return a random number between 0 and 1, like nextDouble(), but shall not debit the entropy count.
        Returns:
        a random number that is normally distributed with mean 0 and standard deviation 1.
      • lockForNextGaussian

        protected void lockForNextGaussian()
        Performs whatever locking is needed by nextGaussian().
      • unlockForNextGaussian

        protected void unlockForNextGaussian()
        Releases the locks acquired by lockForNextGaussian().
      • ints

        public java8.util.stream.IntStream ints​(long streamSize)
        Specified by:
        ints in interface Java8CompatRandom
      • ints

        public java8.util.stream.IntStream ints​(long streamSize,
                                                int randomNumberOrigin,
                                                int randomNumberBound)
        Returns a stream producing the given number of pseudorandom ints, each conforming to the given origin (inclusive) and bound (exclusive). This implementation uses nextInt(int, int) to generate these numbers.
        Specified by:
        ints in interface Java8CompatRandom
      • nextInt

        public int nextInt​(int origin,
                           int bound)
        Returns a pseudorandom int value between the specified origin (inclusive) and the specified bound (exclusive).
        Parameters:
        origin - the least value returned
        bound - the upper bound (exclusive)
        Returns:
        a pseudorandom int value between the origin (inclusive) and the bound (exclusive)
        Throws:
        IllegalArgumentException - if origin is greater than or equal to bound
      • ints

        public java8.util.stream.IntStream ints​(int randomNumberOrigin,
                                                int randomNumberBound)

        Returns a stream producing an effectively unlimited number of pseudorandom ints, each conforming to the given origin (inclusive) and bound (exclusive). This implementation uses nextInt(int, int) to generate these numbers.

        Specified by:
        ints in interface Java8CompatRandom
      • longs

        public java8.util.stream.LongStream longs​(long streamSize)
        Specified by:
        longs in interface Java8CompatRandom
      • longs

        public java8.util.stream.LongStream longs()

        If the returned stream is a parallel stream, consuming it in parallel after calling DoubleStream.limit(long) may cause extra entropy to be spuriously consumed.

        Specified by:
        longs in interface Java8CompatRandom
      • longs

        public java8.util.stream.LongStream longs​(long streamSize,
                                                  long randomNumberOrigin,
                                                  long randomNumberBound)

        Returns a stream producing the given number of pseudorandom longs, each conforming to the given origin (inclusive) and bound (exclusive). This implementation uses nextLong(long, long) to generate these numbers.

        Specified by:
        longs in interface Java8CompatRandom
      • nextLong

        public long nextLong​(long origin,
                             long bound)
        Returns a pseudorandom long value between the specified origin (inclusive) and the specified bound (exclusive). This implementation is adapted from the reference implementation of Random.longs(long, long) from JDK 8.
        Parameters:
        origin - the least value returned
        bound - the upper bound (exclusive)
        Returns:
        a pseudorandom long value between the origin (inclusive) and the bound (exclusive)
        Throws:
        IllegalArgumentException - if origin is greater than or equal to bound
      • nextLongNoEntropyDebit

        protected long nextLongNoEntropyDebit()
        Returns the next random long, but does not debit entropy.
        Returns:
        a pseudorandom long with all possible values equally likely.
      • longs

        public java8.util.stream.LongStream longs​(long randomNumberOrigin,
                                                  long randomNumberBound)

        Returns a stream producing an effectively unlimited number of pseudorandom longs, each conforming to the given origin (inclusive) and bound (exclusive). This implementation uses nextLong(long, long) to generate these numbers.

        Specified by:
        longs in interface Java8CompatRandom
      • dump

        public String dump()
        Description copied from interface: Dumpable
        Returns a String representing the state of this object for debugging purposes, including mutable state that Object.toString() usually doesn't return.
        Specified by:
        dump in interface Dumpable
        Returns:
        a representation of this object and its state.
      • getSeed

        public byte[] getSeed()
        Description copied from interface: RepeatableRandom
        Returns the seed.
        Specified by:
        getSeed in interface RepeatableRandom
        Returns:
        The seed data used to initialize this pseudo-random number generator.
      • setSeed

        @Deprecated
        public void setSeed​(long seed)
        Deprecated.
        Some implementations are very slow.
        Sets the seed of this random number generator using a single long seed, if this implementation supports that. If it is capable of using 64 bits or less of seed data (i.e. if {@link #getNewSeedLength()} <= {@link Long#BYTES}), then this method shall replace the entire seed as Random.setSeed(long) does; otherwise, it shall either combine the input with the existing seed as SecureRandom.setSeed(long) does, or it shall generate a new seed using the DefaultSeedGenerator. The latter is a backward-compatibility measure and can be very slow.
        Specified by:
        setSeed in interface Java8CompatRandom
        Overrides:
        setSeed in class Random
      • setSeed

        public void setSeed​(byte[] seed)
        Reseed this PRNG.

        Most subclasses should override setSeedInternal(byte[]) instead of this method, so that they will deserialize properly.

        Specified by:
        setSeed in interface ByteArrayReseedableRandom
        Parameters:
        seed - The PRNG's new seed.
      • getRandomSeeder

        @Nullable
        public SimpleRandomSeeder getRandomSeeder()
        Returns the current seed generator for this PRNG.
        Returns:
        the current seed generator, or null if there is none
      • setSeedInternal

        protected void setSeedInternal​(byte[] seed)
        Sets the seed, and should be overridden to set other state that derives from the seed. Called by setSeed(byte[]), constructors, and readObject(ObjectInputStream). When called after initialization, the lock is always held.
        Parameters:
        seed - The new seed.
      • creditEntropyForNewSeed

        protected void creditEntropyForNewSeed​(int seedLength)
        Updates the entropy count to reflect a reseeding. Sets it to the seed length or the internal state size, whichever is shorter, but never less than the existing entropy count.
        Parameters:
        seedLength - the length of the new seed in bytes
      • initTransientFields

        protected void initTransientFields()
        Called in constructor and readObject to initialize transient fields.
      • checkLength

        protected static byte[] checkLength​(byte[] seed,
                                            int requiredLength)
        Checks that the given seed is the expected length, then returns it.
        Parameters:
        seed - the seed to check
        requiredLength - the expected length
        Returns:
        seed
        Throws:
        IllegalArgumentException - if seed == null || seed.length != requiredLength
      • getEntropyBits

        public long getEntropyBits()
        Description copied from interface: EntropyCountingRandom
        Returns an estimate of the current amount of entropy. Every time the PRNG is reseeded, the entropy count is set to the new seed's length; and every time it is used, it is decreased by the number of random bits in the output rounded up. The amount of entropy can go below zero, giving an indication of how far the entropy has been stretched. This estimate is a lower bound if the seed is perfectly random and is not being reused.
        Specified by:
        getEntropyBits in interface EntropyCountingRandom
        Returns:
        The current estimated amount of entropy.
      • debitEntropy

        protected void debitEntropy​(long bits)
        Record that entropy has been spent, and schedule a reseeding if this PRNG has now spent as much as it's been seeded with.
        Parameters:
        bits - The number of bits of entropy spent.
      • fallbackSetSeedIfInitialized

        protected void fallbackSetSeedIfInitialized()
        Generates and sets a seed using the DefaultSeedGenerator. Used by setSeed(long) in implementations where it can't otherwise fulfill its contract.
      • getNewSeedLength

        public abstract int getNewSeedLength()
        Description copied from interface: ByteArrayReseedableRandom
        Returns the preferred length of a new byte-array seed. "Preferred" is implementation-defined when multiple seed lengths are supported, but should probably usually mean the longest one, since the longer the seed, the more random the output.
        Specified by:
        getNewSeedLength in interface ByteArrayReseedableRandom
        Returns:
        The desired length of a new byte-array seed.
      • supportsMultipleSeedLengths

        protected boolean supportsMultipleSeedLengths()
        If true, the subclass takes responsibility for checking whether the seed is non-null and has a valid length, and should throw an IllegalArgumentException in setSeedInternal(byte[]) if not.
        Returns:
        true if this PRNG supports seed lengths other than getNewSeedLength(); false otherwise.