Class BaseRandom
- java.lang.Object
-
- java.util.Random
-
- io.github.pr0methean.betterrandom.prng.BaseRandom
-
- All Implemented Interfaces:
ByteArrayReseedableRandom
,EntropyCountingRandom
,Java8CompatRandom
,RepeatableRandom
,Dumpable
,Serializable
- Direct Known Subclasses:
BaseSplittableRandomAdapter
,CipherCounterRandom
,Cmwc4096Random
,MersenneTwisterRandom
,Pcg128Random
,Pcg64Random
,RandomWrapper
,XorShiftRandom
public abstract class BaseRandom extends Random implements ByteArrayReseedableRandom, RepeatableRandom, Dumpable, EntropyCountingRandom, Java8CompatRandom
AbstractRandom
with a seed field and an implementation of entropy counting.- Author:
- Chris Hennick
- See Also:
- Serialized Form
-
-
Field Summary
Fields Modifier and Type Field Description protected static int
ENTROPY_OF_DOUBLE
The number of pseudorandom bits innextDouble()
.protected static int
ENTROPY_OF_FLOAT
The number of pseudorandom bits innextFloat()
.protected AtomicLong
entropyBits
Stores the entropy estimate backinggetEntropyBits()
.protected ReentrantLock
lock
Lock to prevent concurrent modification of the RNG's internal state.protected AtomicReference<SimpleRandomSeeder>
randomSeeder
If the referent is non-null, it will be invoked to reseed this PRNG whenever random output is taken andgetEntropyBits()
called immediately afterward would return zero or negative.protected byte[]
seed
The seed this PRNG was seeded with, as a byte array.protected boolean
superConstructorFinished
Set by the constructor once eitherRandom()
orRandom(long)
has returned.
-
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 theDefaultSeedGenerator
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 givenMoreObjects.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 aString
representing the state of this object for debugging purposes, including mutable state thatObject.toString()
usually doesn't return.protected static int
entropyOfInt(int origin, int bound)
Calculates the entropy in bits, rounded up, of a randomint
betweenorigin
(inclusive) andbound
(exclusive).protected static int
entropyOfLong(long origin, long bound)
Calculates the entropy in bits, rounded up, of a randomlong
betweenorigin
(inclusive) andbound
(exclusive).protected void
fallbackSetSeedIfInitialized()
Generates and sets a seed using theDefaultSeedGenerator
.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 ofnextGaussian()
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 bynextGaussian()
.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 pseudorandomdouble
value between 0.0 (inclusive) and the specified bound (exclusive).double
nextDouble(double origin, double bound)
Returns a pseudorandomdouble
value between the specified origin (inclusive) and bound (exclusive).protected double
nextDoubleNoEntropyDebit()
Returns the next randomdouble
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>>
EnextEnum(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 pseudorandomint
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 pseudorandomlong
value between zero (inclusive) and the specified bound (exclusive).long
nextLong(long origin, long bound)
Returns a pseudorandomlong
value between the specified origin (inclusive) and the specified bound (exclusive).protected long
nextLongNoEntropyDebit()
Returns the next randomlong
, but does not debit entropy.boolean
preferSeedWithLong()
Indicates whetherRandom.setSeed(long)
is recommended overByteArrayReseedableRandom.setSeed(byte[])
when the seed is already in the form of along
.void
setRandomSeeder(SimpleRandomSeeder randomSeeder)
Registers this PRNG with theSimpleRandomSeeder
for the correspondingSeedGenerator
, 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 anIllegalArgumentException
insetSeedInternal(byte[])
if not.protected void
unlockForNextGaussian()
Releases the locks acquired bylockForNextGaussian()
.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 bywithProbability(double)
to generate a boolean with a specified probability of returning true, after checking thatprobability
is strictly between 0 and 1.
-
-
-
Field Detail
-
ENTROPY_OF_FLOAT
protected static final int ENTROPY_OF_FLOAT
The number of pseudorandom bits innextFloat()
.- See Also:
- Constant Field Values
-
ENTROPY_OF_DOUBLE
protected static final int ENTROPY_OF_DOUBLE
The number of pseudorandom bits innextDouble()
.- See Also:
- Constant Field Values
-
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 andgetEntropyBits()
called immediately afterward would return zero or negative.
-
lock
protected final ReentrantLock lock
Lock to prevent concurrent modification of the RNG's internal state.
-
entropyBits
protected final AtomicLong entropyBits
Stores the entropy estimate backinggetEntropyBits()
.
-
seed
protected volatile byte[] seed
The seed this PRNG was seeded with, as a byte array. Used bygetSeed()
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 eitherRandom()
orRandom(long)
has returned. Intended forsetSeed(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(int seedSizeBytes) throws SeedException
Seed the RNG using theDefaultSeedGenerator
to create a seed of the specified size.- Parameters:
seedSizeBytes
- The number of bytes to use for seed data.- Throws:
SeedException
- if theDefaultSeedGenerator
fails to generate a seed.
-
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 randomint
betweenorigin
(inclusive) andbound
(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 randomlong
betweenorigin
(inclusive) andbound
(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 whenprobability >= 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 bywithProbability(double)
to generate a boolean with a specified probability of returning true, after checking thatprobability
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 ofarray
; 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 oflist
; usually inferred by the compiler.- Parameters:
list
- A non-emptyList
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 ofenumClass
; 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 examplewithProbability(double)
, which uses 53 random bits but outputs only one, and thus debits only 1 bit of entropy).
-
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 interfaceJava8CompatRandom
- Overrides:
nextBytes
in classRandom
-
nextInt
public int nextInt()
- Specified by:
nextInt
in interfaceJava8CompatRandom
- Overrides:
nextInt
in classRandom
-
nextInt
public int nextInt(int bound)
- Specified by:
nextInt
in interfaceJava8CompatRandom
- Overrides:
nextInt
in classRandom
-
nextLong
public long nextLong()
Returns the next pseudorandom, uniformly distributed long value from this random number generator's sequence. Unlike the inherited implementation inRandom.nextLong()
, ones in BetterRandom generally can be expected to return all 264 possible values.- Specified by:
nextLong
in interfaceJava8CompatRandom
- Overrides:
nextLong
in classRandom
-
nextLong
public long nextLong(long bound)
Returns a pseudorandomlong
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
- ifbound
is not positive
-
nextDouble
public double nextDouble(double bound)
Returns a pseudorandomdouble
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
- ifbound
is not positive
-
nextDouble
public double nextDouble(double origin, double bound)
Returns a pseudorandomdouble
value between the specified origin (inclusive) and bound (exclusive).- Parameters:
origin
- the least value returnedbound
- the upper bound (exclusive)- Returns:
- a pseudorandom
double
value between the origin (inclusive) and the bound (exclusive) - Throws:
IllegalArgumentException
- iforigin
is greater than or equal tobound
-
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 interfaceJava8CompatRandom
-
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 interfaceJava8CompatRandom
-
doubles
public java8.util.stream.DoubleStream doubles(long streamSize)
- Specified by:
doubles
in interfaceJava8CompatRandom
-
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 usesnextDouble(double, double)
to generate these numbers.- Specified by:
doubles
in interfaceJava8CompatRandom
-
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 usesnextGaussian()
.- Parameters:
streamSize
- the number of doubles to generate.- Returns:
- a stream of
streamSize
normally-distributed random doubles.
-
nextBoolean
public boolean nextBoolean()
- Specified by:
nextBoolean
in interfaceJava8CompatRandom
- Overrides:
nextBoolean
in classRandom
-
nextFloat
public float nextFloat()
- Specified by:
nextFloat
in interfaceJava8CompatRandom
- Overrides:
nextFloat
in classRandom
-
nextDouble
public double nextDouble()
- Specified by:
nextDouble
in interfaceJava8CompatRandom
- Overrides:
nextDouble
in classRandom
-
nextDoubleNoEntropyDebit
protected double nextDoubleNoEntropyDebit()
Returns the next randomdouble
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 inRandom
, this implementation is lockless.- Specified by:
nextGaussian
in interfaceJava8CompatRandom
- Overrides:
nextGaussian
in classRandom
-
internalNextGaussian
protected double internalNextGaussian(java8.util.function.DoubleSupplier nextDouble)
Core of a reimplementation ofnextGaussian()
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, likenextDouble()
, 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 bynextGaussian()
.
-
unlockForNextGaussian
protected void unlockForNextGaussian()
Releases the locks acquired bylockForNextGaussian()
.
-
ints
public java8.util.stream.IntStream ints(long streamSize)
- Specified by:
ints
in interfaceJava8CompatRandom
-
ints
public java8.util.stream.IntStream ints()
- Specified by:
ints
in interfaceJava8CompatRandom
-
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 usesnextInt(int, int)
to generate these numbers.- Specified by:
ints
in interfaceJava8CompatRandom
-
nextInt
public int nextInt(int origin, int bound)
Returns a pseudorandomint
value between the specified origin (inclusive) and the specified bound (exclusive).- Parameters:
origin
- the least value returnedbound
- the upper bound (exclusive)- Returns:
- a pseudorandom
int
value between the origin (inclusive) and the bound (exclusive) - Throws:
IllegalArgumentException
- iforigin
is greater than or equal tobound
-
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 interfaceJava8CompatRandom
-
longs
public java8.util.stream.LongStream longs(long streamSize)
- Specified by:
longs
in interfaceJava8CompatRandom
-
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 interfaceJava8CompatRandom
-
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 interfaceJava8CompatRandom
-
nextLong
public long nextLong(long origin, long bound)
Returns a pseudorandomlong
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 returnedbound
- the upper bound (exclusive)- Returns:
- a pseudorandom
long
value between the origin (inclusive) and the bound (exclusive) - Throws:
IllegalArgumentException
- iforigin
is greater than or equal tobound
-
nextLongNoEntropyDebit
protected long nextLongNoEntropyDebit()
Returns the next randomlong
, 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 interfaceJava8CompatRandom
-
dump
public String dump()
Description copied from interface:Dumpable
Returns aString
representing the state of this object for debugging purposes, including mutable state thatObject.toString()
usually doesn't return.
-
getSeed
public byte[] getSeed()
Description copied from interface:RepeatableRandom
Returns the seed.- Specified by:
getSeed
in interfaceRepeatableRandom
- 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 asRandom.setSeed(long)
does; otherwise, it shall either combine the input with the existing seed asSecureRandom.setSeed(long)
does, or it shall generate a new seed using theDefaultSeedGenerator
. The latter is a backward-compatibility measure and can be very slow.- Specified by:
setSeed
in interfaceJava8CompatRandom
- Overrides:
setSeed
in classRandom
-
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 interfaceByteArrayReseedableRandom
- Parameters:
seed
- The PRNG's new seed.
-
addSubclassFields
protected abstract MoreObjects.ToStringHelper addSubclassFields(MoreObjects.ToStringHelper original)
Adds the fields that were not inherited from BaseRandom to the givenMoreObjects.ToStringHelper
for dumping.- Parameters:
original
- aMoreObjects.ToStringHelper
object.- Returns:
original
with the fields not inherited from BaseRandom written to it.
-
setRandomSeeder
public void setRandomSeeder(@Nullable SimpleRandomSeeder randomSeeder)
Registers this PRNG with theSimpleRandomSeeder
for the correspondingSeedGenerator
, to schedule reseeding when we run out of entropy. Unregisters this PRNG with the previousSimpleRandomSeeder
if it had a different one.- Parameters:
randomSeeder
- aSeedGenerator
whoseSimpleRandomSeeder
will be used to reseed this PRNG, or null to stop using one.
-
getRandomSeeder
@Nullable public SimpleRandomSeeder getRandomSeeder()
Returns the current seed generator for this PRNG.- Returns:
- the current seed generator, or null if there is none
-
preferSeedWithLong
public boolean preferSeedWithLong()
Description copied from interface:ByteArrayReseedableRandom
Indicates whetherRandom.setSeed(long)
is recommended overByteArrayReseedableRandom.setSeed(byte[])
when the seed is already in the form of along
.- Specified by:
preferSeedWithLong
in interfaceByteArrayReseedableRandom
- Returns:
- true if
Random.setSeed(long)
will tend to perform better thanByteArrayReseedableRandom.setSeed(byte[])
.
-
setSeedInternal
protected void setSeedInternal(byte[] seed)
Sets the seed, and should be overridden to set other state that derives from the seed. Called bysetSeed(byte[])
, constructors, andreadObject(ObjectInputStream)
. When called after initialization, thelock
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 checkrequiredLength
- the expected length- Returns:
seed
- Throws:
IllegalArgumentException
- ifseed == 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 interfaceEntropyCountingRandom
- 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 theDefaultSeedGenerator
. Used bysetSeed(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 interfaceByteArrayReseedableRandom
- 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 anIllegalArgumentException
insetSeedInternal(byte[])
if not.- Returns:
- true if this PRNG supports seed lengths other than
getNewSeedLength()
; false otherwise.
-
needsReseedingEarly
public boolean needsReseedingEarly()
Description copied from interface:EntropyCountingRandom
If true, this PRNG needs reseeding even though its entropy is positive. Added to deal withEntropyBlockingRandomWrapper
.- Specified by:
needsReseedingEarly
in interfaceEntropyCountingRandom
- Returns:
- true if this PRNG needs reseeding regardless of entropy count; false otherwise
-
-