Difference between two random statements [duplicate] - java

This question already has answers here:
Java random numbers using a seed
(7 answers)
Closed 5 years ago.
I want to know why the numbers appearing in the first column will change each time the code is run. The numbers in the second column will always be the same. (83 51 77 90 96 58 35 38 86 54)?
Random randomGenerator = new Random();
Random otherGenerator = new Random(123);
for(int i = 0; i < 10; i++) {
int number1 = 1 + randomGenerator.nextInt(100);
int number2 = 1 + otherGenerator.nextInt(100);
System.out.println("random numbers "+number1+" " +number2);
}

This happens because the Random used for the second column is seeded with a constant 123, while the one for the first column has a seed that varies each time the code is executed.
Note that the values produced by Random are not truly random; they are completely determined by the seed.

The doc says:
Creates a new random number generator using a single long seed. The seed is the initial value of the internal state of the pseudorandom number generator which is maintained by method
You have fixed the initial state of the 2nd generator is fixed and it is from the seed that the next random numbers are generated.
On the other side, if you used System.nanoTime() to generate the seed, you would see each time your generator creates different random numbers.
See: https://docs.oracle.com/javase/7/docs/api/java/util/Random.html#Random(long)

Related

Best way to generate unique Random number in Java

I have to generate unique serial numbers for users consisting of 12 to 13 digits. I want to use random number generator in Java giving the system. Time in milliseconds as a seed to it. Please let me know about the best practice for doing so. What I did was like this
Random serialNo = new Random(System.currentTimeMillis());
System.out.println("serial number is "+serialNo);
Output came out as: serial number is java.util.Random#13d8cc98
For a bit better algorithm pick SecureRandom.
You passed a seed to the random constructor. This will pick a fixed sequence with that number. A hacker knowing the approximate time of calling, might restrict the number of attempts. So another measure is not using the constructor and nextLong at the same spot.
SecureRandom random = new SecureRandom​();
long n = random.nextLong();
A symmetric bit operation might help:
n ^= System.currentMillis();
However there is a unique number generation, the UUID, a unique 128 bits number, two longs. If you xor them (^) the number no longer is that unique, but might still be better having mentioned the circumstantial usage of random numbers.
UUID id = UUID.randomUUID();
long n = id.getLeastSignificantBits() ^ id.getMostSignificantBits();
Create a random number generator using the current time as seed (as you did)
long seed = System.currentTimeMillis();
Random rng = new Random​(seed);
Now, to get a number, you have to use the generator, rng is NOT a number.
long number = rng.nextLong();
According to the documentation, this will give you a pseudorandom number with 281.474.976.710.656 different possible values.
Now, to get a number with a maximum of 13 digits:
long number = rng.nextLong() % 10000000000000;
And to get a number with exactly 13 digits:
long number = (rng.nextLong() % 9000000000000) + 1000000000000;
First, import the Random class:
import java.util.Random;
Then create an instance of this class, with the current milliseconds as its seed:
Random rng = new Random(System.currentTimeMillis());
This line would generate an integer that can have up to 13 digits:
long result = rng.nextLong() % 10000000000000;
This line would generate an integer that always have 13 digits:
long result = rng.nextLong() % 9000000000000 + 1000000000000;
There are three ways to generate Random numbers in java
java.util.Random class
We can generate random numbers of types integers, float, double, long, booleans using this class.
Example :
//Random rand = new Random();
// rand_int1 = rand.nextInt(1000)
Math.random method : Can Generate Random Numbers of double type.
random(), this method returns a double value with a positive sign, greater than or equal to 0.0 and less than 1.0.
Example :
Math.random());
//Gives output 0.15089348615777683
ThreadLocalRandom class
This class is introduced in java 1.7 to generate random numbers of type integers, doubles, booleans etc
Example :
//int random_int1 = ThreadLocalRandom.current().nextInt();
// Print random integers
//System.out.println("Random Integers: " + random_int1);

How to generate a SecureRandom number with a specific bit range [duplicate]

This question already has answers here:
How do I generate random integers within a specific range in Java?
(72 answers)
Closed 1 year ago.
I have maximum number of bits that is not bit aligned E.g. 35 and required to generate unique random number from 1 - 68719476734 (max number for 35 bits).
Could use SecureRandom but will have to extract 5 bytes out of it and convert to Long maybe, but chances of collision seem to a concern. What are some options to generate a random for this range.
Could i seed this random with nanoTime maybe if there is a collision and regenerate in this range.
First, a few comments:
The max value for 35 bits is 34359738367, not 68719476734.
68719476734 is not even the max value for 36 bits, 68719476735 is.
Do not seed a SecureRandom. That reduces the security of it.
To generate a 35-bit random number, excluding value zero, just generate a long random value, take the last 35 bits, and redo if the value is zero.
SecureRandom r = new SecureRandom();
long value;
do {
value = r.nextLong() & ((1L << 35) - 1);
} while (value == 0);
There may be a better way, but perhaps this can help. The first simply prints the single number generated from a stream. The second masks off the required bits. Interesting that the values for the same seed are different (which I can't explain). But the first method which allows a range might be sufficient for what you want. I am clearly not an expert on this but provided it to foster some ideas.
SecureRandom r = new SecureRandom();
r.setSeed(23);
// generate a sum of 1 element to get the element from the stream.
long v = 0;
while (v == 0) {
v = r.longs(1,1L<<34, (1L<<35)-1).sum();
}
System.out.println(v);
System.out.println(64-Long.numberOfLeadingZeros(v));
r.setSeed(23);
long vv = 0;
while (vv == 0) {
vv = r.nextLong()&((1L<<35)-1);
}
System.out.println(vv);
System.out.println(64-Long.numberOfLeadingZeros(vv));
prints
31237208166
35
9741674490
34
My assumption here was that the stream version above would not be provided if the random numbers did not meet the secure requirements.

Using Random Class but my variable isn't random? [duplicate]

This question already has answers here:
Java random always returns the same number when I set the seed?
(7 answers)
Closed 2 years ago.
for(int i = 0; i < emojiCnt; i++){
Random rand = new Random(1000);
int randNum = rand.nextInt((3) + 1);
switch (randNum){
case 1:
//Code
case 2:
//Code
case 3:
//Code
default:
//Code
}
randNum = rand.nextInt((10) + 1);
}
Every time I run the code, it gives the same result and is not random? I reassign randNum so that it will go to a random number but it doesn't seem to change?
Random rand = new Random(1000); tells java to create a Random, based on the initial seed of 1000. This results in random, but still reproducable results.
If you want different values for each execution, use Random rand = new Random(); instead.
You seed the RNG with a constant by calling ... = new Random(1000);. With the same seed, one will always get the same sequence of "random numbers". Do not seed (... = new Random();), and the values should be "random".
A comment on randomness and programming:
Without an external entropy generator, a computer is generally not able to generate true randomness. Thus, random number generators operate by using an inital seed to generate a pseudo-random sequence. The sequence normally satisfies all conditions expected by a truly random sequence, but is deterministic once the seed is known. More information can be found on the wikipedia article on Random number generators.
Try to use this code to get random numbers:
Random rand = new Random();
int maxNumber = 1000;
rand.nextInt(maxNumber)
This code will bring you random values between 0 and 1000

Generating a number between a given range and 0 [duplicate]

This question already has answers here:
How do I generate random integers within a specific range in Java?
(72 answers)
Closed 3 years ago.
I am trying to generate a random number between a given range and 0.
The code given below helped me to generate a number between the given range.
(int)(Math.random() * 13 + 4);
Is it possible to modify this code to generate a value between 4 and 10 and also 0
use this for generate a value between 4 and 10
public static double getRandomDoubleBetweenRange(int 4, int 10){
double x = (Math.random()*((10-4)+1))+4;
return x;
}
I suspect that this is a homework question so I won't spoonfeed you with the correct answer but give you the tools you need to answer it yourself:
public static double random()
Returns a double value with a positive sign, greater than or equal to
0.0 and less than 1.0. Returned values are chosen pseudorandomly with (approximately) uniform distribution from that range.
Source: https://docs.oracle.com/javase/8/docs/api/java/lang/Math.html#random--
Casting a double to an int performs a narrowing primitive conversion. In the range you use and for positive numbers, you can just treat it like a floor (removing the numbers after the decimal point).
If you want to know about the details, see: https://docs.oracle.com/javase/specs/jls/se7/html/jls-5.html#jls-5.1.3
Something like this would do the cause.
//stream 3 random numbers from 0 to 10 and pick any of them
int random = new Random().ints(3, 0, 11).findAny().getAsInt();
//print it
System.out.println(random);
UPDATE 2:
// make a list of 0 and 4-10
List<Integer> list = Arrays.asList(0,4,5,6,7,8,9,10);
// used for picking random number from within a list
Random random = new SecureRandom();
// get random index element from a list
int randomNumber = list.get(random.nextInt(list.size()));
// print
System.out.println(randomNumber);

Java random numbers not random?

I was trying to explain the random number generator in Java to a friend when he kept getting the same numbers every time he ran the program. I created my own simpler version of the same thing and I too am getting the same exact numbers he was getting every time I run the program.
What am I doing wrong?
import java.util.*;
public class TestCode{
public static void main(String[] args){
int sum = 0;
Random rand = new Random(100);
for(int x = 0; x < 100; x++){
int num = (rand.nextInt(100)) + 1;
sum += num;
System.out.println("Random number:" + num);
}
//value never changes with repeated program executions.
System.out.println("Sum: " + sum);
}
}
The final five numbers out of the 100 are:
40
60
27
56
53
You have seeded the random generator with a constant value 100. It's deterministic, so that will generate the same values each run.
I'm not sure why you chose to seed it with 100, but the seed value has nothing to do with the range of values that are generated (that's controlled by other means, such as the call to nextInt that you already have).
To get different values each time, use the Random constructor with no arguments, which uses the system time to seed the random generator.
Quoting from the Javadoc for the parameterless Random constructor:
Creates a new random number generator. 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.
Quoting the actual code in the parameterless Random constructor:
public Random() {
this(seedUniquifier() ^ System.nanoTime());
}
This:
Random rand = new Random(100);
You're giving the random number generator the same seed (100) each time you start the program. Give it something like the output from System.currentTimeMillis() and that should give you different numbers for each invocation.
Random number generators are really only pseudo-random. That is, they use deterministic means to generate sequences that appear random given certain statistical criteria.
The Random(long seed) constuctor allows you to pass in a seed that determines the sequence of pseudo-random numbers.
Please see the below code to generate a random number from a pool of random numbers.
Random r = new Random(System.currentTimeMillis());
double[] rand = new double[500];
for(int i=0;i<100;i++){
rand[i] = r.nextDouble();
}
double random_number = rand[randomInt];

Categories