Judging from the docs Random.nextInt(int n) , which obviously should solve the same problem, they seem to have come to the conclusion that you cannot do better than “oversampling if out of range”, but the penalty is expected to be insignificant.
From the docs:
The algorithm is a bit complicated. It rejects values that lead to an uneven distribution (due to the fact that 2 31 is not divisible by n). The probability of deviation of a value depends on n. In the worst case, n = 2 30 +1, for which the probability of deviation is 1/2, and the expected number of iterations before the end of the cycle is 2.
I would suggest that you simply use the randomizing constructor you mentioned, and iterate until you reach a value that is in the range, like this:
public static BigInteger rndBigInt(BigInteger max) { Random rnd = new Random(); do { BigInteger i = new BigInteger(max.bitLength(), rnd); if (i.compareTo(max) <= 0) return i; } while (true); } public static void main(String... args) { System.out.println(rndBigInt(new BigInteger("8180385048"))); }
For your specific case (with max = 8180385048), the probability of repeated repetition, even once, is about 4.8%,% , so do not worry :-)
source share