To avoid repeating what have been said multiple times, I am showing an alternative for those that need a cryptographically stronger pseudo-random number generator by using the SecureRandom class, which extends the class Random
. From source one can read:
This class provides a cryptographically strong random number generator
(RNG). A cryptographically strong random number minimally complies
with the statistical random number generator tests specified in FIPS
140-2, Security Requirements for Cryptographic Modules, section 4.9.1.
Additionally, SecureRandom must produce non-deterministic output.
Therefore any seed material passed to a SecureRandom object must be
unpredictable, and all SecureRandom output sequences must be
cryptographically strong, as described in RFC 1750: Randomness
Recommendations for Security.
A caller obtains a SecureRandom instance via the no-argument
constructor or one of the getInstance methods:
SecureRandom random = new SecureRandom();
Many SecureRandom implementations are in the form of a pseudo-random number generator
(PRNG), which means they use a deterministic algorithm to produce a
pseudo-random sequence from a true random seed. Other implementations
may produce true random numbers, and yet others may use a combination
of both techniques.
To generate a random number between a min
and max
values inclusive:
public static int generate(SecureRandom secureRandom, int min, int max) {
return min + secureRandom.nextInt((max - min) + 1);
}
for a given a min
(inclusive) and max
(exclusive) values:
return min + secureRandom.nextInt((max - min));
A running code example:
public class Main {
public static int generate(SecureRandom secureRandom, int min, int max) {
return min + secureRandom.nextInt((max - min) + 1);
}
public static void main(String[] arg) {
SecureRandom random = new SecureRandom();
System.out.println(generate(random, 0, 2 ));
}
}
Source such as stackoverflow, baeldung, geeksforgeeks provide comparisons between Random
and SecureRandom
classes.
From baeldung one can read:
The most common way of using SecureRandom is to generate int, long,
float, double or boolean values:
int randomInt = secureRandom.nextInt();
long randomLong = secureRandom.nextLong();
float randomFloat = secureRandom.nextFloat();
double randomDouble = secureRandom.nextDouble();
boolean randomBoolean = secureRandom.nextBoolean();
For generating int values we can pass an upper bound as a parameter:
int randomInt = secureRandom.nextInt(upperBound);
In addition, we can generate a stream of values for int, double and long:
IntStream randomIntStream = secureRandom.ints();
LongStream randomLongStream = secureRandom.longs();
DoubleStream randomDoubleStream = secureRandom.doubles();
For all streams we can explicitly set the stream size:
IntStream intStream = secureRandom.ints(streamSize);
This class offers several other options (e.g., choosing the underlying random number generator) that are out of the scope of this question.