When I enter 42 for the seed value, it provides a certain sequence of numbers and reproduces the same ones every time the program is used. But the sequence of numbers in my program doesn't match up with the sequence of numbers in another program. I need to figure out how to make both of them provide the same output of random numbers when both seed values are set to 42. Is this the correct format for getting a seed value from the user? What could be causing the numbers to not match up? Thanks for the help.
public class SampleTest {
public static void main(String[] args) {
System.out.println("Please enter a seed value: ");
Scanner in = new Scanner(System.in);
seed = in.nextInt();
Random ranGen = new Random(seed);
You say that you are seeding the random number generator with the same seed, making the same calls, and yet the number sequences are different.
I think there are two plausible explanations for what is happening:
Your two applications are in fact not seeding the generator and using it the same way. There are lots of mistakes that could have been made, including accidentally using more than one generator (as per #PD's comment).
The applications are running on platforms with different implementations of the generator class. (This would be contraindicated by the javadocs for Random, which specify the exact generator formulae that should be used.)
The way to figure out which of these two possibilities is occurring is to write a simple test application that just prints the sequence of numbers produced by a Random instance with a given seed, then run it on both machines.
Related
I have a requirement where users will have to see a pin generated for an order and has to be shared/used as authorization code for that particular order.
So I am looking for a library which can generate random unique pins of 6 digit length which can be used for each transaction.
Please share your thoughts on this..
Thanks..
You can try SecureRandom
Extract From here
java.security.SecureRandom class: 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.
java.util.Random class: The classes defined in Random are not cryptographically strong, and the numbers chosen are not completely random because a definite mathematical algorithm (based on Donald E. Knuthâs subtractive random number generator algorithm) is used to select them. Therefore, it is not safe to use this class for tasks that require high level of security, like creating a random password etc.
Example using SecureRandom:
SecureRandom sr = SecureRandom.getInstance("SHA1PRNG");
int myInt = sr.nextInt(9000000) + 1000000;
Please use the Apache library.
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
<version>3.6</version>
</dependency>
int random = RandomUtils.nextInt(1, 7);
Ref: https://www.java67.com/2018/01/3-ways-to-generate-random-integers-on.html
I am looking for a library which can generate random unique pins
If you generate a random integer, it's not guaranteed to always be unique. With 6 numeric digits, there's a one in a million chance that users could get the same order number. You could increase the number of digits or also allow alphabet characters to decrease the chances of getting the same order number.
However, the only way to truly ensure each order number is unique is to keep a running tally of total number of orders. Then each user's order number is literally the n'th order you've received.
You can manually generate pin in java using built-in **java.util.Random class **. You can use this in authentication to generate six digits random number pin.
int rand_int1 = rand.nextInt(1000000);
if rand_int1 has 6 digits
print(rand_int1)
else
generate(again)
this will generate a six digit random number.
There are 2 constructors of Random class
public Random()
public Random(long seed)
The description for the second constructor as per oracle states as
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 next(int).
I did not understand it completely. And I did not find any articles/book which clearly explains why,when and how it is used.
Can any one explain please?
If you use the constructor with the seed, you will get a repeatable sequence, so it's good for testing. If you use the constructor without the seed, you don't know what sequence of random-like numbers will be produced.
A pseudorandom number generator works by repeatedly generating a new number based on the one it has previously generated. That means that if you always have the same first "random" number, and you use the same pseudorandom number generator to generate the second, you'll always have the same second "random" number as well.
The first Random constructor constructs a pseudorandom number generator with a nondeterminate seed (first number in the sequence), so you'll almost always end up with a different sequence of "random" numbers. The second Random constructor constructs a pseudorandom number generator with whatever seed you want, so if you give it the same seed, you'll always get the same sequence.
Here's an example. If you create a Random like this:
Random yourRandom = new Random();
it will start off with some seed. That seed could be 42, 121, 3810, whatever. You can never be sure when you create it. All the random numbers it generates are based off of that seed, and so since it nearly always uses a different seed, you'll nearly always get different "random" numbers out of it.
On the other hand, if you create a Random like this instead:
Random yourOtherRandom = new Random(36);
all the numbers yourOtherRandom generates will be calculated starting from 36. Since the first number (36) is the same, and the second number is calculated from the first, etc., everything yourOtherRandom generates will be the same every time you run your program.
This is a fun one!
The Random number generation is not random at all. If you use the same seed and ask it for a bunch of random numbers, you will get the same sequence. This is important as it allows different computers to predictably generate the same sequence as long as they have shared the seed.
If you do not specify a seed, then one is chosen for you that is very unlikely to be chosen by any other VM in the world. BUT, if someone were to guess the seed you used, they would be able to generate the same sequence of numbers.
From Google search:Random search
The Random generator is a Pseudorandom number generator. That means that it is, in fact, not a random number generator but only some clever algorithm that produces fully deterministic numbers that just look like random.
When the generator is used, each time it produces a random number it modifies its internal state in order to produce a different number at the next call. However, at the beginning the internal state of this algorithm must be initialised, and the value that is used for this initialisation is commonly called seed. The parameterless constructor makes a seed on its own, based on system time, while the other constructor lets you to put your seed, which allows you to make it repeatable - the same seed (and the same generator) will produce the same sequence of numbers.
If you are interested, here is the source code of the Random class from OpenJDK (i.e. the open source implementation of Java, but it should be functionally equivalent). The constructor with seed is at line 135, the setSeed method is at line 168 and e.g. the nextInt method is at line 328 which just calls a private method next which is at line 198 and which is where all the magic happens. It also has javadoc with the reference to the (probably more mathematical) description of this kind of generator.
I wonder whether what you want to ask is about distinguishing the default constructor and argument constructor. When you instantiate a new Random object, you can code this:
Random random=new Random();
In this way, we invoke the default constructor, i.e no argument constructor.
But if you code this:
Random random=new Random(47);
we invoke a constructor which argument is 47.
It is similar to C language; a seed will "randomly" create a number if you use the same seed and no matter when it will not change. But if you choose the first method, the number will modify once running!
Simple question
java.lang.Math.random()
How does this work? Meaning there is no seed input, so does it generate a random number off the system time? Meaning like if two calls were made to this function at .00001s away from eachother (basically the same time), would it produce the same result?
Thanks!
The javadoc explains how it works:
When this method is first called, it creates a single new pseudorandom-number generator, exactly as if by the expression
new java.util.Random()
This new pseudorandom-number generator is used thereafter for all calls to this method and is used nowhere else.
Returned values are chosen pseudorandomly with (approximately) uniform distribution from that range. When this method is first called, it creates a single new pseudorandom-number generator, exactly as if by the expression new java.util.Random
This new pseudorandom-number generator is used thereafter for all calls to this method and is used nowhere else. This method is properly synchronized to allow correct use by more than one thread. However, if many threads need to generate pseudorandom numbers at a great rate, it may reduce contention for each thread to have its own pseudorandom-number generator.
In order to understand how does this code runs you must go through the various Random Number generator algorithms. In actual practice theres no concept call random numbers if you google "Psuedo Random Number Algorithm" then you can have a better insight about the various concepts.
Answering your Question : Yes there will be different if the Random Number Generator Algorithm is based on time (usually they are).
But at the output if u write
Random obj1 = new Random()
int p = obj1.nextInt(10%2)
int q = obj1.nextGaussian();
theres a chance that the same number may appear more than once. It is because the Number generated is undoubtedly a unique number but it due to various parameters the obtained output is filtered and so theres a probabilty that the ouput can be same
There are two principal means of generating random (really pseudo-random) numbers:
the Random class generates random integers, doubles, longs and so on, in various ranges.
the static method Math.random generates doubles between 0 (inclusive) and 1 (exclusive).
To generate random integers:
do not use Math.random (it produces doubles, not integers)
use the Random class to generate random integers between 0 and N.
To generate a series of random numbers as a unit, you need to use a single Random object - do not create a new Random object for each new random number.
Other alternatives are:
SecureRandom, a cryptographically strong subclass of Random
ThreadLocalRandom, intended for multi-threaded cases
import java.util.Random;
/** Generate 10 random integers in the range 0..99. */
public final class RandomInteger {
public static final void main(String... aArgs){
log("Generating 10 random integers in range 0..99.");
//note a single Random object is reused here
Random randomGenerator = new Random();
for (int idx = 1; idx <= 10; ++idx){
int randomInt = randomGenerator.nextInt(100);
log("Generated : " + randomInt);
}
log("Done.");
}
private static void log(String aMessage){
System.out.println(aMessage);
}
}
I am using a simple random calculations for a small range with 4 elements.
indexOfNext = new Random().nextInt(4); //randomize 0 to 3
When I attach the debugger I see that for the first 2-3 times every time the result is 1.
Is this the wrong method for a small range or I should implement another logic (detecting previous random result)?
NOTE: If this is just a coincidence, then using this method is the wrong way to go, right? If yes, can you suggest alternative method? Shuffle maybe? Ideally, the alternative method would have a way to check that next result is not the same as the previous result.
Don't create a new Random() each time, create one object and call it many times.
This is because you need one random generator and many numbers from its
random sequence, as opposed to having many random generators and getting
just the 1st numbers of the random sequences they generate.
You're abusing the random number generator by creating a new instance repeatedly. (This is due to the implementation setting a starting random number value that's a very deterministic function of your system clock time). This ruins the statistical properties of the generator.
You should create one instance, then call nextInt as you need numbers.
One thing you can do is hold onto the Random instance. It has to seed itself each time you instantiate it and if that seed is the same then it will generate the same random sequence each time.
Other options are converting to SecureRandom, but you definitely want to hold onto that random instance to get the best random number performance. You really only need SecureRandom is you are randomly generating things that have security implications. Like implementing crypto algorithms or working around such things.
"Random" doesn't mean "non-repeating", and you cannot judge randomness by short sequences. For example, imagine that you have 2 sequences of 1 and 0:
101010101010101010101010101010101
and
110100100001110100100011111010001
Which looks more random? Second one, of course. But when you take any short sequence of 3-4-5 numbers from it, such sequence will look less random than taken from the first one. This is well-known and researched paradox.
A pseudo-random number generator requires a seed to work. The seed is a bit array which size depends on the implementation. The initial seed for a Random can either be specified manually or automatically assigned.
Now there are several common ways of assigning a random seed. One of them is ++currentSeed, the other is current timestamp.
It is possible that java uses System.currentTimeMillis() to get the timestamp and initialize the seed with it. Since the resolution of the timestamp is at most a millisecond (it differs on some machines, WinXP AFAIK had 3ms) all Random instances instantiated in the same millisecond-resolution window will have the same seed.
Another feature of pseudo-random number generators is that if they have the same seed, they return the same numbers in the same order.
So if you get the first pseudo-random number returned by several Randoms initialized with the same seed you are bound to get the same number for a few times. And I suspect that's what's happening in your case.
It seems that the number 1 has a 30% chance of showing its self which is more than other numbers. You can read this link for more information on the subject.
You can also read up on Benford's law.
How does the seed value passed to Java's random number generator effect its output? How would i go about figuring out which numbers it will output if i know the seed value?
Also are some seed values better than others at producing more psudo-randomness than others?
You cannot generate truly random numbers in software, because software is deterministic: given some input, it will in principle always generate a predictable output.
So, to get random numbers, a number of algorithms have been invented that generate sequences of numbers that look random (but are not really - that's why they are called pseudo-random numbers).
Such an algorithm starts with some start value, the seed, and then does some calculations with it to generate the next pseudo-random number.
If the algorithm is any good, then there should be no difference in seed values: one seed value should not be better than any other in generating random numbers.
Often, the current time is taken as the seed value, so that each time you generate a sequence of numbers, you get a different sequence. Note that if you use the same seed value, you will get the same sequence of pseudo-random numbers each time you run it.
If you use pseudo-random numbers for cryptographic purposes, you should be very careful, because if an attacker knows the seed value then he can re-generate the sequence of random numbers which might compromise the security of your system. For really secure systems, people use special hardware-based random number generators, which can generate truly random numbers. Java has a class java.security.SecureRandom to interface with such systems.
See Random number generation on Wikipedia for a lot more detail and information on different algorithms.