Class MTRandom
- All Implemented Interfaces:
Serializable
,RandomGenerator
As a subclass of Random
, this class provides a single canonical Random.next(int)
method for generating bits in the pseudo random number sequence. Anyone using
this class should invoke the public inherited methods (Random.nextInt()
, Random.nextFloat()
etc.) to obtain values as normal. This class should provide a drop-in
replacement for the standard implementation of java.util.Random
with the additional
advantage of having a far longer period and the ability to use a far larger seed value.
This is not a cryptographically strong source of randomness and should not be used for cryptographic systems or in any other situation where true random numbers are required.
- Version:
- 1.1
- Author:
- David Beaumont, Copyright 2005,2023
- See Also:
-
Nested Class Summary
Nested classes/interfaces inherited from interface java.util.random.RandomGenerator
RandomGenerator.ArbitrarilyJumpableGenerator, RandomGenerator.JumpableGenerator, RandomGenerator.LeapableGenerator, RandomGenerator.SplittableGenerator, RandomGenerator.StreamableGenerator
-
Constructor Summary
ConstructorsConstructorDescriptionMTRandom()
Creates a newMTRandom
instance.MTRandom
(boolean compatible) This version of the constructor can be used to implement identical behaviour to the original C code version of this algorithm including exactly replicating the case where the seed value had not been set prior to callinggenrand_int32
.MTRandom
(byte[] seedBytes) This version of the constructor initialises the class with the given byte array.MTRandom
(int[] seedArray) This version of the constructor initialises the class with the given integer array.MTRandom
(long seed) This version of the constructor simply initialises the class with the given 64 bit seed value. -
Method Summary
Modifier and TypeMethodDescriptionprotected int
next
(int bits) static int[]
pack
(byte[] bytes) Packs a byte array of seed data into a more efficient int array.void
setSeed
(byte[] seedBytes) This method resets the state of this instance using the byte array of seed data provided.void
setSeed
(int[] seedArray) This method resets the state of this instance using the integer array of seed data provided.void
setSeed
(long seed) Methods inherited from class java.util.Random
doubles, doubles, doubles, doubles, from, ints, ints, ints, ints, longs, longs, longs, longs, nextBoolean, nextBytes, nextDouble, nextFloat, nextGaussian, nextInt, nextInt, nextLong
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
Methods inherited from interface java.util.random.RandomGenerator
isDeprecated, nextDouble, nextDouble, nextExponential, nextFloat, nextFloat, nextGaussian, nextInt, nextLong, nextLong
-
Constructor Details
-
MTRandom
public MTRandom()Creates a newMTRandom
instance. This constructor sets the seed of the random number generator to a value very likely to be distinct from any other invocation of this constructor.Note that the method to generate a default seed is explicitly not defined and may change without notice as improvements are made. If you need to rely on deterministic output, you should always set seed data explicitly.
-
MTRandom
public MTRandom(boolean compatible) This version of the constructor can be used to implement identical behaviour to the original C code version of this algorithm including exactly replicating the case where the seed value had not been set prior to callinggenrand_int32
.If
compatible
is set totrue
, then the algorithm will be seeded with the same default value as was used in the original C code. Furthermore, theRandom.setSeed(long)
method, which must take a 64 bitlong
value, will be limited to using only the lower 32 bits of the seed to facilitate seamless migration of existing C code into Java where identical behaviour is required.While useful for ensuring backwards compatibility, it is advised that this feature not be used unless specifically required, due to the reduction in strength of the seed value.
If
compatible
is set tofalse
, this constructor behaves exactly the same asMTRandom()
.- Parameters:
compatible
- Compatibility flag for replicating original C behaviour.
-
MTRandom
public MTRandom(long seed) This version of the constructor simply initialises the class with the given 64 bit seed value. For a better random number sequence this seed value should contain as much entropy as possible.- Parameters:
seed
- The seed value with which to initialise this class.
-
MTRandom
public MTRandom(byte[] seedBytes) This version of the constructor initialises the class with the given byte array. All the data will be used to initialise this instance.- Parameters:
seedBytes
- The non-empty byte array of seed information.- Throws:
NullPointerException
- if the buffer is null.IllegalArgumentException
- if the buffer has zero length.
-
MTRandom
public MTRandom(int[] seedArray) This version of the constructor initialises the class with the given integer array. All the data will be used to initialise this instance.- Parameters:
seedArray
- The non-empty integer array of seed information.- Throws:
NullPointerException
- if the buffer is null.IllegalArgumentException
- if the buffer has zero length.
-
-
Method Details
-
setSeed
public void setSeed(long seed) This method resets the state of this instance using the 64 bits of seed data provided. Note that if the same seed data is passed to two different instances of MTRandom (both of which share the same compatibility state) then the sequence of numbers generated by both instances will be identical.
If this instance was initialised in 'compatibility' mode then this method will only use the lower 32 bits of any seed value passed in and will match the behaviour of the original C code exactly with respect to state initialisation.
-
setSeed
public void setSeed(byte[] seedBytes) This method resets the state of this instance using the byte array of seed data provided. Note that calling this method is equivalent to callingsetSeed(pack(seedBytes))
and in particular will result in a new integer array being generated during the call. If you wish to retain this seed data to allow the pseudo random sequence to be restarted then it would be more efficient to use thepack(byte[])
method to convert it into an integer array first, and then use that to re-seed the instance.- Parameters:
seedBytes
- The non-empty byte array of seed information.- Throws:
NullPointerException
- if the buffer is null.IllegalArgumentException
- if the buffer has zero length.
-
setSeed
public void setSeed(int[] seedArray) This method resets the state of this instance using the integer array of seed data provided. This is the canonical way of resetting the pseudo random number sequence.- Parameters:
seedArray
- The non-empty integer array of seed information.- Throws:
NullPointerException
- if the buffer is null.IllegalArgumentException
- if the buffer has zero length.
-
next
protected int next(int bits) This method forms the basis for generating a pseudo random number sequence from this class. If given a value of 32, this method behaves identically to the genrand_int32 function in the original C code and ensures that using the standard nextInt() function (inherited from Random) we are able to replicate behaviour exactly.
Note that where the number of bits requested is not equal to 32 then bits will simply be masked out from the top of the returned integer value. That is to say that:
will not give the same result asmt.setSeed(12345); int foo = mt.nextInt(16) + (mt.nextInt(16) << 16);
mt.setSeed(12345); int foo = mt.nextInt(32);
-
pack
public static int[] pack(byte[] bytes) Packs a byte array of seed data into a more efficient int array.This simple utility method can be used in cases where a byte array of seed data is to be used to repeatedly re-seed the random number sequence. Packing the byte array into an integer array first using this method, and then invoking
setSeed(int[])
with that, removes the need to re-pack the byte array each timesetSeed(byte[])
is called.If the length of the byte array is not a multiple of 4 then it is implicitly padded with zeros as necessary. For example:
byte[] { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06 }
becomes:int[] { 0x04030201, 0x00000605 }
Note that this method will not complain if the given byte array is empty and will produce an empty integer array, but the
setSeed()
method will throw an exception if the empty integer array is passed to it.- Parameters:
bytes
- The non-null byte array to be packed.- Returns:
- An integer array of packed bytes.
- Throws:
NullPointerException
- if the given byte array is null.
-