Seeding a secure random number in java - java

Will two java.security.SecureRandom instances which are seeded with the same value initially give the same sequence of random numbers?
I am asking this because I want the same sequence of random numbers in both the client and the server. What if both of them are using the same seed value. Will the sequence be the same, or is there any way that the sequence can be made the same?

From the API docs:
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.

What if both of them are using the same seed value. Will the sequence be the same?
No, they definitely won't. At least not in Oracle's Java 7 SDK implementation. See my sample code in this SO post. It appears that the implementation may elect to use additional sources of randomness, in addition to the provided seed.

Related

How ı build random number not using random library or etc.?

I have to generate random numbers in two different places in the project and I do it using the system clock, but I have to get different numbers in both. How can I do that?
You could use a loop surrounded by calls to System.nanoTime(), then use the least significant bits of their difference as random seed. Once you have, say, 128 bits you can use it as seed for a pseudo random number generator.
There is an article posted in the wiki at java-gaming.org about generating pseudo-random numbers that might be worth perusing. Pseudo-random number generators He shows what he calls an "Old School" method of creating them using a combination of polynomials and modular division. Plus links to other types of PRNGs.

Why random of 0 to 4 is 1 most of times?

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 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.

Java Random seed

I need to test out a Java program 20 times and need to set the random seed so that the tests can be repeated. If I were to set the initial seed as 0 and then increment by 1 at each run (i.e. 1,2,3 etc), would this method still ensure complete randomness, even though the seeds are not far apart?
Thank you
Any seed will provide the same level of randomness as any other seed for a standard PRNG like the one included with Java. So it's fine to use an incrementing seed for tests.
You might want to consider using a better random number generator though. The one included with Java yields noticeable repeating patterns if you render the values as an image (I can't find a reference offhand, but I recall it being apparent). I'd recommend the Mersenne Twister (there are Java versions) as an alternative that's fast and has a very long period so you won't easily see patterns.
If you use a seed of 0 the sequence of random numbers will be repeatable from that point. You would only need to use a different random seed if you wanted a different sequence. i.e. you should be able to set the seed once per test.
Why not just use the current time as the seed? ie, System.currentTimeMillis() ?
Do you need a number or a string? I use UUID.randomUUID().toString() to get a UUID for my tests when I need strings, but if you need a number then you can use System.nanoTime().

Reimplementing mkpasswd

On Linux I am used to using mkpasswd to generate random passwords to use, on OS X however I don't have this command. Instead of sshing in to my vps every time, I wanted to re implement it using Java. What I have done is pick at random 4 lower case letters, 2 upper case letters, 2 symbols (/ . , etc) and 2 numbers. Then I create a vector and shuffle that too.
Do you think this is good enough randomization?
If you use java.security.SecureRandom instead of java.util.Random then it's probably secure. SecureRandom provides a "cryptographically strong pseudo-random number generator (PRNG)". I.e. it ensures that the seed cannot easily be guessed and that the numbers generated have high entropy.
yes, it is. If you are using java.util.Random:
An instance of this class is used to generate a stream of pseudorandom numbers. The class uses a 48-bit seed, which is modified using a linear congruential formula. (See Donald Knuth, The Art of Computer Programming, Volume 2, Section 3.2.1.)
The algorithms implemented by class Random use a protected utility method that on each invocation can supply up to 32 pseudorandomly generated bits.
EDIT
in response to a comment:
/**
* 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.
*/
public Random() {
this(++seedUniquifier + System.nanoTime());
}
private static volatile long seedUniquifier = 8682522807148012L;
There is a similar pwgen command available in the Mac Ports.
Depends on where your entropy comes from. Using rand() or similar functions that your particular language comes with may not be secure.
On OSX you can use /dev/random I think.
It might be OK, but you should allow some randomization in password lengths perhaps.
If your program became popular it would become a weakness that the password length was public knowledge. Also randomize the exact ratio of lowercase:uppercase:symbols:numbers a little.
Why not just compile mkpasswd on your OS X host?

Categories

Resources