Class RandomWrapper<T extends Random>
- java.lang.Object
-
- java.util.Random
-
- io.github.pr0methean.betterrandom.prng.BaseRandom
-
- io.github.pr0methean.betterrandom.prng.adapter.RandomWrapper<T>
-
- All Implemented Interfaces:
ByteArrayReseedableRandom
,EntropyCountingRandom
,RepeatableRandom
,Dumpable
,Serializable
- Direct Known Subclasses:
EntropyBlockingRandomWrapper
,ThreadLocalRandomWrapper
public class RandomWrapper<T extends Random> extends BaseRandom
Wraps any
Random
as aRepeatableRandom
andByteArrayReseedableRandom
. Can be used to encapsulate away a change of implementation in midstream.Caution: This depends on the delegate's thread-safety. When used with a vanilla
Random
, this means that its output for the same seed will vary when accessed concurrently from multiple threads, at least on JDK 7 and 8, if the calls include e.g.BaseRandom.nextLong()
,nextGaussian()
orBaseRandom.nextDouble()
. However,nextInt()
will still be transactional.- Author:
- Chris Hennick
- See Also:
- Serialized Form
-
-
Field Summary
-
Fields inherited from class io.github.pr0methean.betterrandom.prng.BaseRandom
ENTROPY_OF_DOUBLE, ENTROPY_OF_FLOAT, entropyBits, lock, randomSeeder, seed, superConstructorFinished
-
-
Constructor Summary
Constructors Constructor Description RandomWrapper(T wrapped)
Creates an instance wrapping the givenRandom
.
-
Method Summary
All Methods Static Methods Instance Methods Concrete Methods Modifier and Type Method Description protected MoreObjects.ToStringHelper
addSubclassFields(MoreObjects.ToStringHelper original)
Adds the fields that were not inherited from BaseRandom to the givenMoreObjects.ToStringHelper
for dumping.int
getNewSeedLength()
Returns the preferred length of a new byte-array seed.byte[]
getSeed()
Returns the wrapped PRNG's seed, if we know it.T
getWrapped()
Returns the PRNG this RandomWrapper is currently wrapping.protected 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
nextDoubleNoEntropyDebit()
Returns the next randomdouble
between 0.0 (inclusive) and 1.0 (exclusive), but does not debit entropy.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)
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
.protected void
setInitiallyKnownSeed(byte[] seed)
UpdatesBaseRandom.seed
andBaseRandom.entropyBits
without reseeding the wrapped PRNG.void
setSeed(long seed)
Sets the seed of this random number generator using a single long seed, if this implementation supports that.protected void
setSeedInternal(byte[] seed)
Delegates to one ofByteArrayReseedableRandom.setSeed(byte[])
,SecureRandom.setSeed(byte[])
orRandom.setSeed(long)
.void
setWrapped(T wrapped)
Replaces the wrapped PRNG with the given one on subsequent calls.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
inBaseRandom.setSeedInternal(byte[])
if not.String
toString()
boolean
usesParallelStreams()
static RandomWrapper<Random>
wrapJavaUtilRandom(byte[] seed)
Creates an instance wrapping a basicRandom
.static RandomWrapper<Random>
wrapJavaUtilRandom(long seed)
Creates an instance wrapping a basicRandom
.static RandomWrapper<Random>
wrapJavaUtilRandom(SeedGenerator seedGenerator)
Creates an instance wrapping a basicRandom
.static RandomWrapper<SecureRandom>
wrapSecureRandom(byte[] seed)
Creates an instance wrapping a basicSecureRandom
with a given seed.-
Methods inherited from class io.github.pr0methean.betterrandom.prng.BaseRandom
checkLength, checkValidRange, creditEntropyForNewSeed, debitEntropy, doubles, doubles, doubles, doubles, dump, entropyOfInt, entropyOfLong, fallbackSetSeedIfInitialized, gaussians, gaussians, getEntropyBits, getRandomSeeder, initTransientFields, internalNextGaussian, ints, ints, ints, ints, lockForNextGaussian, longs, longs, longs, longs, nextDouble, nextDouble, nextDouble, nextElement, nextElement, nextEnum, nextInt, nextLong, nextLong, nextLong, setRandomSeeder, setSeed, unlockForNextGaussian, withProbability, withProbabilityInternal
-
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, wait, wait, wait
-
Methods inherited from interface io.github.pr0methean.betterrandom.EntropyCountingRandom
needsReseedingEarly
-
-
-
-
Method Detail
-
wrapJavaUtilRandom
public static RandomWrapper<Random> wrapJavaUtilRandom(long seed)
Creates an instance wrapping a basicRandom
.- Parameters:
seed
- the seed- Returns:
- an instance
-
wrapJavaUtilRandom
public static RandomWrapper<Random> wrapJavaUtilRandom(byte[] seed)
Creates an instance wrapping a basicRandom
.- Parameters:
seed
- the seed; must be 8 bytes- Returns:
- an instance
-
wrapSecureRandom
public static RandomWrapper<SecureRandom> wrapSecureRandom(byte[] seed)
Creates an instance wrapping a basicSecureRandom
with a given seed.- Parameters:
seed
- the seed- Returns:
- an instance
-
wrapJavaUtilRandom
public static RandomWrapper<Random> wrapJavaUtilRandom(SeedGenerator seedGenerator) throws SeedException
Creates an instance wrapping a basicRandom
.- Parameters:
seedGenerator
- the generator used to generate the seed- Returns:
- an instance
- Throws:
SeedException
- ifseedGenerator
failed to generate the initial seed
-
setInitiallyKnownSeed
protected void setInitiallyKnownSeed(byte[] seed)
UpdatesBaseRandom.seed
andBaseRandom.entropyBits
without reseeding the wrapped PRNG. Called by thewrapJavaUtilRandom
overloads that take the seed as a parameter, since the seed isn't available from the PRNG once it's been passed to the constructor.- Parameters:
seed
- the seed
-
usesParallelStreams
public boolean usesParallelStreams()
- Overrides:
usesParallelStreams
in classBaseRandom
- Returns:
- true if this PRNG creates parallel streams; false otherwise.
-
next
protected int next(int bits)
Description copied from class:BaseRandom
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 exampleBaseRandom.withProbability(double)
, which uses 53 random bits but outputs only one, and thus debits only 1 bit of entropy).- Specified by:
next
in classBaseRandom
-
getWrapped
public T getWrapped()
Returns the PRNG this RandomWrapper is currently wrapping.- Returns:
- the wrapped
Random
instance
-
setWrapped
public void setWrapped(T wrapped)
Replaces the wrapped PRNG with the given one on subsequent calls.- Parameters:
wrapped
- anRandom
instance to wrap
-
addSubclassFields
protected MoreObjects.ToStringHelper addSubclassFields(MoreObjects.ToStringHelper original)
Description copied from class:BaseRandom
Adds the fields that were not inherited from BaseRandom to the givenMoreObjects.ToStringHelper
for dumping.- Specified by:
addSubclassFields
in classBaseRandom
- Parameters:
original
- aMoreObjects.ToStringHelper
object.- Returns:
original
with the fields not inherited from BaseRandom written to it.
-
getSeed
public byte[] getSeed()
Returns the wrapped PRNG's seed, if we know it. When this RandomWrapper is wrapping a passed-inRandom
that's not aRepeatableRandom
, we won't know the seed until the nextBaseRandom.setSeed(byte[])
orsetSeed(long)
call lets us set it ourselves, and so anUnsupportedOperationException
will be thrown until then.- Specified by:
getSeed
in interfaceRepeatableRandom
- Overrides:
getSeed
in classBaseRandom
- Returns:
- The seed data used to initialize this pseudo-random number generator.
- Throws:
UnsupportedOperationException
- if this RandomWrapper doesn't know the wrapped PRNG's seed.
-
setSeed
public void setSeed(long seed)
Description copied from class:BaseRandom
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.- Overrides:
setSeed
in classBaseRandom
- See Also:
ByteArrayReseedableRandom.preferSeedWithLong()
-
setSeedInternal
protected void setSeedInternal(byte[] seed)
Delegates to one ofByteArrayReseedableRandom.setSeed(byte[])
,SecureRandom.setSeed(byte[])
orRandom.setSeed(long)
.- Overrides:
setSeedInternal
in classBaseRandom
- Parameters:
seed
- The new seed.
-
supportsMultipleSeedLengths
protected boolean supportsMultipleSeedLengths()
Description copied from class:BaseRandom
If true, the subclass takes responsibility for checking whether the seed is non-null and has a valid length, and should throw anIllegalArgumentException
inBaseRandom.setSeedInternal(byte[])
if not.- Overrides:
supportsMultipleSeedLengths
in classBaseRandom
- Returns:
- true if this PRNG supports seed lengths other than
BaseRandom.getNewSeedLength()
; false otherwise.
-
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
- Overrides:
preferSeedWithLong
in classBaseRandom
- Returns:
- true if
Random.setSeed(long)
will tend to perform better thanByteArrayReseedableRandom.setSeed(byte[])
.
-
getNewSeedLength
public 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
- Specified by:
getNewSeedLength
in classBaseRandom
- Returns:
- The desired length of a new byte-array seed.
-
nextBytes
public void nextBytes(byte[] bytes)
Description copied from class:BaseRandom
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.- Overrides:
nextBytes
in classBaseRandom
-
nextInt
public int nextInt()
- Overrides:
nextInt
in classBaseRandom
-
nextInt
public int nextInt(int bound)
- Overrides:
nextInt
in classBaseRandom
-
nextLongNoEntropyDebit
protected long nextLongNoEntropyDebit()
Description copied from class:BaseRandom
Returns the next randomlong
, but does not debit entropy.- Overrides:
nextLongNoEntropyDebit
in classBaseRandom
- Returns:
- a pseudorandom
long
with all possible values equally likely.
-
nextBoolean
public boolean nextBoolean()
- Overrides:
nextBoolean
in classBaseRandom
-
nextFloat
public float nextFloat()
- Overrides:
nextFloat
in classBaseRandom
-
nextDoubleNoEntropyDebit
public double nextDoubleNoEntropyDebit()
Description copied from class:BaseRandom
Returns the next randomdouble
between 0.0 (inclusive) and 1.0 (exclusive), but does not debit entropy.- Overrides:
nextDoubleNoEntropyDebit
in classBaseRandom
- Returns:
- a pseudorandom
double
.
-
nextGaussian
public double nextGaussian()
Description copied from class:BaseRandom
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.- Overrides:
nextGaussian
in classBaseRandom
-
-