ovunccetin
ovunccetin

Reputation: 8663

Does SecureRandom guarantee distinct values each time?

I need to generate cryptographically secure, random and unique strings each of which will be used as an access token actually. For this purpose, I plan to use Java's SecureRandom class. But, I'm not sure that SecureRandom guarantees the uniqueness. In other words, does SecureRandom produces a different value on each time of the generation?

It seems like creating the instance with a seed value (i.e. new SecureRandom(byte[] seed)) may work. But, I'm not sure of that. Moreover, this answer states that the seed is neither safe nor portable. Does seed value serve my purpose?

If you have suggestions other than SecureRandom I want to hear them also.

Upvotes: 3

Views: 4415

Answers (2)

M A
M A

Reputation: 72874

You could leverage the Stream API support for generating an IntStream from the SecureRandom:

SecureRandom random = new SecureRandom();
OfInt iterator = random.ints().distinct().iterator();

int random = iterator.next();

The ints method returns an "effectively unlimited stream of pseudorandom int values", which you can make distinct and obtain an iterator over the elements.

Given that there are 2^32 possible values, I would guess this should be enough for practical usages.

Upvotes: 1

Erwin Bolwidt
Erwin Bolwidt

Reputation: 31299

No, a SecureRandom instance does not guarantee unique results. If it did guarantee that, it wouldn't be entirely random, as you would know that you couldn't get a result that you already received.

Setting the seed value does not improve this situation. It also doesn't make it worse, because the seed you pass is added (supplements) the seed that was internally generated by the SecureRandom implementation.

If you want guaranteed unique random numbers, you need to keep all the previously generated numbers, and then check when you generate new number if it has already been returned. If it has, you need to generate a new number (and repeat the check).

However, if the number that you generate is significantly large, the chance of generating a non-unique number becomes insignificantly small. Try generating a number of 256 bits or more (32 bytes). This is also the mechanism the UUIDs use to generate "unique" numbers. These are also not guaranteed to be unique, but you'd have to wait a very, very long time (on average) before you get a duplicate.

Upvotes: 11

Related Questions