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
Randomas aRepeatableRandomandByteArrayReseedableRandom. 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.ToStringHelperaddSubclassFields(MoreObjects.ToStringHelper original)Adds the fields that were not inherited from BaseRandom to the givenMoreObjects.ToStringHelperfor dumping.intgetNewSeedLength()Returns the preferred length of a new byte-array seed.byte[]getSeed()Returns the wrapped PRNG's seed, if we know it.TgetWrapped()Returns the PRNG this RandomWrapper is currently wrapping.protected intnext(int bits)Generates the next pseudorandom number.booleannextBoolean()voidnextBytes(byte[] bytes)Generates random bytes and places them into a user-supplied byte array.doublenextDoubleNoEntropyDebit()Returns the next randomdoublebetween 0.0 (inclusive) and 1.0 (exclusive), but does not debit entropy.floatnextFloat()doublenextGaussian()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.intnextInt()intnextInt(int bound)protected longnextLongNoEntropyDebit()Returns the next randomlong, but does not debit entropy.booleanpreferSeedWithLong()Indicates whetherRandom.setSeed(long)is recommended overByteArrayReseedableRandom.setSeed(byte[])when the seed is already in the form of along.protected voidsetInitiallyKnownSeed(byte[] seed)UpdatesBaseRandom.seedandBaseRandom.entropyBitswithout reseeding the wrapped PRNG.voidsetSeed(long seed)Sets the seed of this random number generator using a single long seed, if this implementation supports that.protected voidsetSeedInternal(byte[] seed)Delegates to one ofByteArrayReseedableRandom.setSeed(byte[]),SecureRandom.setSeed(byte[])orRandom.setSeed(long).voidsetWrapped(T wrapped)Replaces the wrapped PRNG with the given one on subsequent calls.protected booleansupportsMultipleSeedLengths()If true, the subclass takes responsibility for checking whether the seed is non-null and has a valid length, and should throw anIllegalArgumentExceptioninBaseRandom.setSeedInternal(byte[])if not.StringtoString()booleanusesParallelStreams()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 basicSecureRandomwith 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 basicSecureRandomwith 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- ifseedGeneratorfailed to generate the initial seed
-
setInitiallyKnownSeed
protected void setInitiallyKnownSeed(byte[] seed)
UpdatesBaseRandom.seedandBaseRandom.entropyBitswithout reseeding the wrapped PRNG. Called by thewrapJavaUtilRandomoverloads 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:
usesParallelStreamsin classBaseRandom- Returns:
- true if this PRNG creates parallel streams; false otherwise.
-
next
protected int next(int bits)
Description copied from class:BaseRandomGenerates 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:
nextin classBaseRandom
-
getWrapped
public T getWrapped()
Returns the PRNG this RandomWrapper is currently wrapping.- Returns:
- the wrapped
Randominstance
-
setWrapped
public void setWrapped(T wrapped)
Replaces the wrapped PRNG with the given one on subsequent calls.- Parameters:
wrapped- anRandominstance to wrap
-
addSubclassFields
protected MoreObjects.ToStringHelper addSubclassFields(MoreObjects.ToStringHelper original)
Description copied from class:BaseRandomAdds the fields that were not inherited from BaseRandom to the givenMoreObjects.ToStringHelperfor dumping.- Specified by:
addSubclassFieldsin classBaseRandom- Parameters:
original- aMoreObjects.ToStringHelperobject.- Returns:
originalwith 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-inRandomthat's not aRepeatableRandom, we won't know the seed until the nextBaseRandom.setSeed(byte[])orsetSeed(long)call lets us set it ourselves, and so anUnsupportedOperationExceptionwill be thrown until then.- Specified by:
getSeedin interfaceRepeatableRandom- Overrides:
getSeedin 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:BaseRandomSets 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:
setSeedin classBaseRandom- See Also:
ByteArrayReseedableRandom.preferSeedWithLong()
-
setSeedInternal
protected void setSeedInternal(byte[] seed)
Delegates to one ofByteArrayReseedableRandom.setSeed(byte[]),SecureRandom.setSeed(byte[])orRandom.setSeed(long).- Overrides:
setSeedInternalin classBaseRandom- Parameters:
seed- The new seed.
-
supportsMultipleSeedLengths
protected boolean supportsMultipleSeedLengths()
Description copied from class:BaseRandomIf true, the subclass takes responsibility for checking whether the seed is non-null and has a valid length, and should throw anIllegalArgumentExceptioninBaseRandom.setSeedInternal(byte[])if not.- Overrides:
supportsMultipleSeedLengthsin classBaseRandom- Returns:
- true if this PRNG supports seed lengths other than
BaseRandom.getNewSeedLength(); false otherwise.
-
preferSeedWithLong
public boolean preferSeedWithLong()
Description copied from interface:ByteArrayReseedableRandomIndicates whetherRandom.setSeed(long)is recommended overByteArrayReseedableRandom.setSeed(byte[])when the seed is already in the form of along.- Specified by:
preferSeedWithLongin interfaceByteArrayReseedableRandom- Overrides:
preferSeedWithLongin classBaseRandom- Returns:
- true if
Random.setSeed(long)will tend to perform better thanByteArrayReseedableRandom.setSeed(byte[]).
-
getNewSeedLength
public int getNewSeedLength()
Description copied from interface:ByteArrayReseedableRandomReturns 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:
getNewSeedLengthin interfaceByteArrayReseedableRandom- Specified by:
getNewSeedLengthin classBaseRandom- Returns:
- The desired length of a new byte-array seed.
-
nextBytes
public void nextBytes(byte[] bytes)
Description copied from class:BaseRandomGenerates 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:
nextBytesin classBaseRandom
-
nextInt
public int nextInt()
- Overrides:
nextIntin classBaseRandom
-
nextInt
public int nextInt(int bound)
- Overrides:
nextIntin classBaseRandom
-
nextLongNoEntropyDebit
protected long nextLongNoEntropyDebit()
Description copied from class:BaseRandomReturns the next randomlong, but does not debit entropy.- Overrides:
nextLongNoEntropyDebitin classBaseRandom- Returns:
- a pseudorandom
longwith all possible values equally likely.
-
nextBoolean
public boolean nextBoolean()
- Overrides:
nextBooleanin classBaseRandom
-
nextFloat
public float nextFloat()
- Overrides:
nextFloatin classBaseRandom
-
nextDoubleNoEntropyDebit
public double nextDoubleNoEntropyDebit()
Description copied from class:BaseRandomReturns the next randomdoublebetween 0.0 (inclusive) and 1.0 (exclusive), but does not debit entropy.- Overrides:
nextDoubleNoEntropyDebitin classBaseRandom- Returns:
- a pseudorandom
double.
-
nextGaussian
public double nextGaussian()
Description copied from class:BaseRandomReturns 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:
nextGaussianin classBaseRandom
-
-