Is it guaranteed that 2 sequential calls to secure random will give different numbers?

Using SecureRandom is there a guarantee that 2 sequential calls will not return the same number?
If this is a strict requirement from client API side, is the following loop in the code redundant or not?

Random random = SecureRandom.getInstance("SHA1PRNG");  
long value1 = (long)(r.nextDouble() * LIMIT) + 1;  
long value2 = (long)(r.nextDouble() * LIMIT);  

while(value1 == value2) {  
   value2 = (long)(r.nextDouble() * LIMIT);  
}
Jon Skeet
people
quotationmark

I wouldn't expect there to be. Each call should be independent - requiring the next call to not give the same result as the previous one means it's not as random, IMO.

To take a smaller example, imagine we didn't have nextDouble but a method which returned a value in the range 1 to 3 inclusive. By removing the possibility of returning the same value twice, you've effectively constrained each call to a 50/50 choice, for no obvious reason. You'd be giving extra information about the next call to anyone who could observe "this" call.

Now obviously with double there's a much bigger range - so there's a much smaller of two genuinely randomly-picked values being the same. Not quite 1 in 264, but pretty large.

You've reduced that somewhat by your arithmetic, of course - even if nextDouble() did guarantee to always return different values, it's entirely possible for two double values to have the same result when multiplied by LIMIT and then cast to long. Imagine if LIMIT is 2 for example... how many possible values would you expect to see?

So no, I don't think the code you've got is redundant if you have a strict client requirement.

people

See more on this question at Stackoverflow