Random data is the collection of data with no determined order.
What is pseudo random data?
Pseudo random data is a statistically random data produced by a computer algorithm. Since the data is produced by an algorithm, pseudo random data is not actual random data.
There are 4 primary approaches to product random data in Java.
a. Using Math.random() method
b. Using Random class
c. Using ThreadLocalRandom class
d. Using SecureRandom class
Approach 1: Using Math.random() method
Math.random() method return a double positive value that greater than or equal to 0.0 and less than 1.0.
Signature
public static double random()
Example 1: Get a random integer between two values, the returned value is >= min and less than max.
private static int getRandomNumberMinInclusiveMaxExclusive(int min, int max) {
return (int) (Math.random() * (max - min) + min);
}
Example 2: Get aRandom number that is inclusive at both the
minimum and the maximum.
private static int getRandomIntMaxAndMinInclusive(int min, int max) {
return (int) Math.floor(Math.random() * (max - min + 1) + min);
}
Find the below working application.
MathRandomDemo.java
package com.sample.app;
public class MathRandomDemo {
// Get random integer between two values, the returned value is >= min and less
// than max
private static int getRandomNumberMinInclusiveMaxExclusive(int min, int max) {
return (int) (Math.random() * (max - min) + min);
}
// Random number is inclusive at both the minimum and the maximum
private static int getRandomIntMaxAndMinInclusive(int min, int max) {
return (int) Math.floor(Math.random() * (max - min + 1) + min);
}
public static void main(String[] args) {
for (int i = 0; i < 10; i++)
System.out.println("random number between 10 and 20 is : " + getRandomNumberMinInclusiveMaxExclusive(10, 20));
System.out.println("----------------------");
for (int i = 0; i < 10; i++)
System.out.println("random number between 10 and 20 is : " + getRandomIntMaxAndMinInclusive(10, 20));
}
}
Sample Output
random number between 10 and 20 is : 16 random number between 10 and 20 is : 12 random number between 10 and 20 is : 14 random number between 10 and 20 is : 12 random number between 10 and 20 is : 12 random number between 10 and 20 is : 13 random number between 10 and 20 is : 15 random number between 10 and 20 is : 19 random number between 10 and 20 is : 12 random number between 10 and 20 is : 10 ---------------------- random number between 10 and 20 is : 18 random number between 10 and 20 is : 13 random number between 10 and 20 is : 17 random number between 10 and 20 is : 16 random number between 10 and 20 is : 18 random number between 10 and 20 is : 17 random number between 10 and 20 is : 16 random number between 10 and 20 is : 16 random number between 10 and 20 is : 10 random number between 10 and 20 is : 18
Approach 2: Using Random class
One drawback of Math.random() class is, it return a double value, what if you want to get a random byte array, long, Boolean etc., Here we can use java.util.Random class.
Below table summarizes the methods provided by Random class to generate random data.
Method |
Description |
public boolean nextBoolean() |
Returns the next pseudorandom, uniformly distributed boolean value from this random number generator's sequence. |
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. |
public double nextDouble() |
Returns the next pseudorandom, uniformly distributed double value between 0.0 and 1.0 from this random number generator's sequence. |
public float nextFloat() |
Returns the next pseudorandom, uniformly distributed float value between 0.0 and 1.0 from this random number generator's sequence. |
synchronized 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. |
public int nextInt() |
Returns the next pseudorandom, uniformly distributed int value from this random number generator's sequence. |
public int nextInt(int bound) |
Returns a pseudorandom, uniformly distributed int value between 0 (inclusive) and the specified value (exclusive), drawn from this random number generator's sequence. |
public long nextLong() |
Returns the next pseudorandom, uniformly distributed long value from this random number generator's sequence. |
Find the below working application.
RandomClassDemo.java
package com.sample.app;
import java.util.Random;
public class RandomClassDemo {
public static void main(String[] args) {
Random random = new Random();
boolean boolValue = random.nextBoolean();
byte[] arr = new byte[10];
random.nextBytes(arr);
double doubleValue = random.nextDouble();
float floatValue = random.nextFloat();
double gaussianValue = random.nextGaussian();
int intValue = random.nextInt();
int intBoundVal = random.nextInt(10);
long longValue = random.nextLong();
System.out.println("boolValue : " + boolValue);
System.out.println("Data in byte array:");
for (byte b : arr) {
System.out.print(b + " ");
}
System.out.println("\ndoubleValue : " + doubleValue);
System.out.println("floatValue : " + floatValue);
System.out.println("gaussianValue : " + gaussianValue);
System.out.println("intValue : " + intValue);
System.out.println("intBoundVal : " + intBoundVal);
System.out.println("longValue : " + longValue);
}
}
Output
boolValue : false Data in byte array: -103 83 -68 -99 86 9 -58 37 -121 -58 doubleValue : 0.20895136759695598 floatValue : 0.4006803 gaussianValue : 1.9802811894382149 intValue : 2089366724 intBoundVal : 4 longValue : 1076180557500076931
Additionally, you can provide a seed while initializing Random object. A random seed is a number used to initialize a pseudorandom number generator.
Example
Random random = new Random(18674109);
Above snippet use 18674109 as seed value.
There are couple of problems with Random class.
a. it internally use an AtomicLong value (as seed) for random number generation. Even though it is thread safe, if multiple threads are working on same Random object, it may lead to some performance implications.
b. It do not provide actual random ness, but only pseudo-randomness. We can address this problem using SecureRandom class, I will explain about this later in this post.
c. If two instances of Random are created with the same seed, and the same sequence of method calls is made for each, they will generate and return identical sequences of numbers.
Approach 3: Using ThreadLocalRandom. Similar to Random class, ThreadLocalRandom class provide nextX methods to generate random data. ThreadLocalRandom is a subclass of Random class.
Since ThreadLocalRandom number generator isolated to the current thread, use of ThreadLocalRandom rather than shared Random objects in concurrent programs will typically encounter much less overhead and contention. Use of ThreadLocalRandom is particularly appropriate when multiple tasks (for example, each a ForkJoinTask use random numbers in parallel in thread pools.
Below table summarizes the methods provided by ThreadLocalRandom to generate random data.
Method |
Description |
public boolean nextBoolean() |
Returns a pseudorandom boolean value. |
public void nextBytes(byte[] bytes) |
Generates random bytes and places them into a user-supplied byte array. |
public double nextDouble() |
Returns a pseudorandom double value between zero (inclusive) and one (exclusive). |
public double nextDouble(double bound) |
Returns a pseudorandom double value between 0.0 (inclusive) and the specified bound (exclusive). This method throws IllegalArgumentException if bound is not positive. |
public double nextDouble(double origin, double bound) |
Returns a pseudorandom double value between the specified origin (inclusive) and bound (exclusive). This method throws an IllegalArgumentException if origin is greater than or equal to bound. |
public float nextFloat() |
Returns a pseudorandom float value between zero (inclusive) and one (exclusive). |
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. |
public int nextInt() |
Returns a pseudorandom int value. |
public int nextInt(int bound) |
Returns a pseudorandom int value between zero (inclusive) and the specified bound (exclusive). This method throws an IllegalArgumentException if bound is not positive. |
public int nextInt(int origin, int bound) |
Returns a pseudorandom int value between the specified origin (inclusive) and the specified bound (exclusive). This method throws an IllegalArgumentException if origin is greater than or equal to bound. |
public long nextLong() |
Returns a pseudorandom long value. |
public long nextLong(long bound) |
Returns a pseudorandom long value between zero (inclusive) and the specified bound (exclusive). This method throws IllegalArgumentException if bound is not positive. |
public long nextLong(long origin, long bound |
Returns a pseudorandom long value between the specified origin (inclusive) and the specified bound (exclusive). throws IllegalArgumentException if origin is greater than or equal to bound. |
Find the below working application.
ThreadLocalRandomDemo.java
package com.sample.app;
import java.util.concurrent.ThreadLocalRandom;
public class ThreadLocalRandomDemo {
public static void main(String[] args) {
ThreadLocalRandom threadLocalRandom = ThreadLocalRandom.current();
boolean boolVal = threadLocalRandom.nextBoolean();
byte[] bytesData = new byte[10];
threadLocalRandom.nextBytes(bytesData);
double doubleVal1 = threadLocalRandom.nextDouble();
double doubleVal2 = threadLocalRandom.nextDouble(10);
double doubleVal3 = threadLocalRandom.nextDouble(0, 10);
float floatVal = threadLocalRandom.nextFloat();
double gaussianVal = threadLocalRandom.nextGaussian();
int intVal1 = threadLocalRandom.nextInt();
int intVal2 = threadLocalRandom.nextInt(10);
int intVal3 = threadLocalRandom.nextInt(0, 10);
long longVal1 = threadLocalRandom.nextLong();
long longVal2 = threadLocalRandom.nextLong(10);
long longVal3 = threadLocalRandom.nextLong(0, 10);
System.out.println("boolVal : " + boolVal);
for (byte b : bytesData) {
System.out.print(b + " ");
}
System.out.println();
System.out.println("doubleVal1 : " + doubleVal1);
System.out.println("doubleVal2 : " + doubleVal2);
System.out.println("doubleVal3 : " + doubleVal3);
System.out.println("floatVal : " + floatVal);
System.out.println("gaussianVal : " + gaussianVal);
System.out.println("intVal1 : " + intVal1);
System.out.println("intVal2 : " + intVal2);
System.out.println("intVal3 : " + intVal3);
System.out.println("longVal1 : " + longVal1);
System.out.println("longVal2 : " + longVal2);
System.out.println("longVal3 : " + longVal3);
}
}
Sample Output
boolVal : false 118 -19 -34 108 62 -97 71 -86 59 126 doubleVal1 : 0.34651766819920815 doubleVal2 : 8.44772447992309 doubleVal3 : 6.626061934684642 floatVal : 0.9201188 gaussianVal : -0.5276663370928654 intVal1 : 1957939933 intVal2 : 1 intVal3 : 9 longVal1 : 3661422727668556698 longVal2 : 8 longVal3 : 2
Note that Instances of ThreadLocalRandom are not cryptographically secure. Better to use java.security.SecureRandom in security-sensitive applications.
Approach 4: Using SecureRandom class.
SecureRandom class provides provides a cryptographically strong random number generator. All SecureRandom output sequences must be cryptographically strong, as described in RFC 1750: Randomness Recommendations for Security.
You can get an instance of SecureRandom algorithm by calling getInstance() or getInstanceStrong() methods.
public static SecureRandom getInstance(String algorithm)
public static SecureRandom getInstance(String algorithm, String provider)
public static SecureRandom getInstance(String algorithm, Provider provider) throws NoSuchAlgorithmException
Returns a SecureRandom object that implements the specified Random Number Generator (RNG) algorithm. 'algorithm' the name of the RNG algorithm. At the time of writing this post, below algorithms supported.
a. NativePRNG
b. NativePRNGBlocking
c. NativePRNGNonBlocking
d. PKCS11
e. SHA1PRNG
f. Windows-PRNG
You can get more details about these algorithms from below link.
public static SecureRandom getInstanceStrong() throws NoSuchAlgorithmException
SecureRandom object that was selected by using the algorithms/providers specified in the securerandom.strongAlgorithms Security property.
Below snippet print the secure random algorithms.
SecureRandomAlgorithms.java
package com.sample.app;
import java.security.Security;
public class SecureRandomAlgorithms {
public static void main(String[] args) {
String secureRandomAlgos = Security.getProperty("securerandom.strongAlgorithms");
System.out.println(secureRandomAlgos);
}
}
Since SecureRandom class extends Random class, all the methods provided by Random class are available to SecureRandom object.
References
https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/security/SecureRandom.html
https://tersesystems.com/blog/2015/12/17/the-right-way-to-use-securerandom/
http://www.ietf.org/rfc/rfc1750.txt
https://openjdk.java.net/jeps/123
https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/util/Random.html
https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/security/Security.html
https://tersesystems.com/blog/2015/12/17/the-right-way-to-use-securerandom/
You may like
How to solve the Error: Could not find or load main?
Quick guide to race condition in Java with examples
How to read the file content using an iterator in Java?
Implement a Closeable iterator in Java
No comments:
Post a Comment