Ensuring independence between streams of random numbers - java

If I pick a seed (say 999) and generate a stream of random numbers, how can I choose a second seed that ensures the second stream of random numbers does not match the first? Does the second seed need to be measurably different from 999? Would something as simple as seed2 = seed1 + 1000 work? The programming language I'm interested in is Java.

Related

Does the difference between random seeds matter?

Will this:
new java.util.Random(/* random seed */ 0)
new java.util.Random(/* random seed */ 1)
result in somehow "less random" / "more similar" random generators than this?
new java.util.Random(/* random seed */ 0)
new java.util.Random(/* random seed */ 1000)
In other words: do I risk having similar series of ints obtained from the random generators if their random seeds are similar?
No, similar seeds, will not produce similar random numbers.
Only same seeds will produce same numbers.
The code to set the seed is:
void setSeed(long seed) {
this.seed = (seed ^ 0x5DEECE66DL) & ((1L << 48) - 1);
..}
This formula avoids that this.seed gets simlar values for the input seed value (used in the constructor, or by setSeed().
However there is some weakness, als explained in
http://dontpanic.42.nl/2011/03/when-random-isn-as-random-as-expected.html
The state updates used to produce pseudo-random numbers are chaotic. Hence, using adjacent seed values results in entirely different state trajectories.
Random numbers are never random. They are entirely pre-defined and given the same seed will always result in the same numbers even over a million different runs of the commands, that is the reason they are called "Pseudorandom". The best thing to do is to seed with a value that will be different each time the program is run and can not be predicted easily such as the current time and date and/or number of clock cycles that have passed.

Trying to create a program that immitates a 6 sided dice using the Math class

I understand I have to use the random method but thats where my understanding ends
The Random class has a nextInt(int) method that makes it easy to select a value:
Random random = new Random(); // ... or possibly reuse an existing Random
int side = random.nextInt(6); // resulting side is in 0...5
In many other languages, there is only a method to obtain an evenly-distributed number between 0 and 1. In those cases, multiplying this value by the size of the range will give you an evenly distributed number in the desired range, and then you simply add an offset to shift the result into the range in question. This is the same principle by which the internals of nextInt() operates.

Random Numbers in Android

I know there are a lot of topics about random number generation in Android and Java in general. I am currently programming an app that rolls 5 dices. I currently use Random() to generate these numbers. This is my code:
Random r = new Random();
a[0] = r.nextInt(6)+1;
a[1] = r.nextInt(6)+1;
a[2] = r.nextInt(6)+1;
d[0] = r.nextInt(6)+1;
d[1] = r.nextInt(6)+1;
Documentation says that Random() without custom seed is sufficient for most tasks. Is it still random enough when I generate 5 random numbers in such short time? Is there any difference if I generate a new Random() object after each random number?
You don't need a new seed each time you generate a random number. The same seed will generate the same random sequence of numbers so you have to worry about generating an unpredictable seed. The default constructor Random() will generate a seed partially based on current time which should be sufficient for your purpose.
If you do not use a custom seed (e.g. based on time or some such non-easily-repeatable itme), then your results will repeat each time you execute (i.e. you will get the same sequence of pseudo random numbers).
You want to add a custom seed so that successive executions of your program do not always have the same result.
While it is not necessary for a simple homework question to use a custom seed, it would be a good idea to add use of a custom seed (so you learn about how to do that and why it may be needed for more complex problem solving).

Java Math.random() How random is it?

I am working on a project that needs to generate two random numbers from a given range (both of them at the same time, one after another) and check if they are equal to each other - if they are, proceed executing other code; if they aren't - generate the numbers again. Now my question is, if we have a range [0;10], and the first randomly generated number turned out to be 5, is the probability of the second number also being 5 as good as any other number? Specifically, does Math.random() have any "defense" against generating same number if it is called twice consecutively? or it "tries" to not generate the same number?
Generating the same number in the range [0,10] twice in succession is a perfectly valid occurrence for any random number generator. If it took any steps to prevent that it wouldn't be random.
On any invocation, the chances of any individual number being chosen should be 1:11, and each choice should be independent of previous choices, so the chances that in a pair the second number matches the first is 1 in 11.
As to how random Math.random() is, it's pseudo-random, meaning it uses an algorithm to generate a series of evenly distributed numbers starting with a "seed" value. It's not suitable for cryptography but quite good for simulations and other non-cryptographic uses.

Random Number Generation without repetition in Java

I would like to get clarifications on Pseudo Random Number generation.
My questions are:
Is there any chance for getting repeated numbers in Pseudo Random Number Generation?
When i googled i found true random number generation. Can i get some algorithms for true random number generation, so that i can use it with
SecureRandom.getInstance(String algorithm)
Please give guidance with priority given to security.
1) Yes, you can generally have repeated numbers in a PRNG. Actually, if you apply the pigeon hole principle, the proof is quite straightforward (ie, suppose you have a PRNG on the set of 32-bit unsigned integers; if you generate more than 2^32 pseudo random numbers, you will certainly have at least one number generated at least 2 times; in practice, that would happen way faster; usually the algorithms for PRNGs will cycle through a sequence, and you have a way to calculate or estimate the size of that cycle, at the end of which every single number will start repeating, and the image of the algorithm is usually way, way smaller than the set from which you take your numbers).
If you need non-repeated numbers (since security seems to be a concern for you, note that this is less secure than a sequence of (pseudo) random numbers in which you allow repeated numbers!!!), you can do as follows:
class NonRepeatedPRNG {
private final Random rnd = new Random();
private final Set<Integer> set = new HashSet<>();
public int nextInt() {
for (;;) {
final int r = rnd.nextInt();
if (set.add(r)) return r;
}
}
}
Note that the nextInt method defined above may never return! Use with caution.
2) No, there's no such thing as an "algorithm for true random number generation", since an algorithm is something known, that you control and can predict (ie, just run it and you have the output; you know exactly its output the next time you run it with the same initial conditions), while a true RNG is completely unpredictable by definition.
For most common non security-related applications (ie, scientific calculations, games, etc), a PRNG will suffice. If security is a concern (ie, you want random numbers for crypto), then a CSPRNG (cryptographycally secure PRNG) will suffice.
If you have an application that cannot work without true randomness, I'm really curious to know more about it.
Yes, any random number generator can repeat. There are three general solutions to the non-duplicate random number problem:
If you want a few numbers from a large range then pick one and reject
it if it is a duplicate. If the range is large, then this won't cause
too many repeated attempts.
If you want a lot of numbers from a small range, then set out all the numbers in an
array and shuffle the array. The Fisher-Yates algorithm is standard for array
shuffling. Take the random numbers in sequence from the shuffled array.
If you want a lot of numbers from a large range then use an appropriately sized
encryption algorithm. E.g. for 64 bit numbers use DES and encrypt 0, 1, 2, 3, ...
in sequence. The output is guaranteed unique because encryption is reversible.
Pseudo RNGs can repeat themselves, but True RNGs can also repeat themselves - if they never repeated themselves they wouldn't be random.
A good PRNG once seeded with some (~128 bit) real entropy is practically indistinguishable from a true RNG. You certainly won't get noticeably more collisions or repetitions than with a true RNG.
Therefore you are unlikely to ever need a true random number generator, but if you do check out the HTTP API at random.org. Their API is backed by a true random source. The randomness comes from atmospheric noise.
If a PRNG or RNG never repeated numbers, it would be... really predictable, actually! Imagine a PRNG over the numbers 1 to 8. You see it print out 2, 5, 7, 3, 8, 4, 6. If the PRNG tried its hardest not to repeat itself, now you know the next number is going to be 1 - that's not random at all anymore!
So PRNGs and RNGs produce random output with repetition by default. If you don't want repetition, you should use a shuffling algorithm like the Fisher-Yates Shuffle ( http://en.wikipedia.org/wiki/Fisher%E2%80%93Yates_shuffle ) to randomly shuffle an array of the numbers you want, in random order.
Also, if you need a source of random number generation for cryptographic purposes, seek out a provider of cryptographic PRNGs for your language. As long as it's cryptographically strong it should be fine - A true RNG is a lot more expensive (or demands latency, such as using random.org) and not usually needed.

Categories

Resources