public static BigInteger nextBigInteger(
		final BigInteger n,
		final RandomGenerator random
	) {
		if (n.compareTo(BigInteger.ONE) < 0) {
			throw new IllegalArgumentException(format(
				"n is smaller than one: %d", n
			));
		}

		BigInteger result = null;
		if (n.bitLength() <= Integer.SIZE - 1) {
			result = BigInteger.valueOf(random.nextInt(n.intValue()));
		} else if (n.bitLength() <= Long.SIZE - 1) {
			result = BigInteger.valueOf(random.nextLong(n.longValue()));
		} else {
			final var rnd = RandomAdapter.of(random);
			do {
				result = new BigInteger(n.bitLength(), rnd).mod(n);
			} while (result.compareTo(n) > 0);
		}

		return result;
	}
Returns a pseudo-random, uniformly distributed int value between 0
(inclusive) and the specified value (exclusive), drawn from the given
random number generator's sequence.

@param n the bound on the random number to be returned. Must be
       positive.
@param random the random engine used for creating the random number.
@return the next pseudo-random, uniformly distributed int value
        between 0 (inclusive) and n (exclusive) from the given random
        number generator's sequence
@throws IllegalArgumentException if n is smaller than 1.
@throws NullPointerException if the given {@code random}
        engine of the maximal value {@code n} is {@code null}.
jenetics.ext/src/main/java/io/jenetics/ext/internal/util/Randoms.java