How to Generate a Random Biginteger Value in Java

How to generate a random BigInteger value in Java?

Use a loop:

BigInteger randomNumber;
do {
randomNumber = new BigInteger(upperLimit.bitLength(), randomSource);
} while (randomNumber.compareTo(upperLimit) >= 0);

on average, this will require less than two iterations, and the selection will be uniform.

Edit: If your RNG is expensive, you can limit the number of iterations the following way:

int nlen = upperLimit.bitLength();
BigInteger nm1 = upperLimit.subtract(BigInteger.ONE);
BigInteger randomNumber, temp;
do {
temp = new BigInteger(nlen + 100, randomSource);
randomNumber = temp.mod(upperLimit);
} while (s.subtract(randomNumber).add(nm1).bitLength() >= nlen + 100);
// result is in 'randomNumber'

With this version, it is highly improbable that the loop is taken more than once (less than one chance in 2^100, i.e. much less than the probability that the host machine spontaneously catches fire in the next following second). On the other hand, the mod() operation is computationally expensive, so this version is probably slower than the previous, unless the randomSource instance is exceptionally slow.

How to generate random BigIntegers larger than 2**64

First you create the number 2^64 with a byte array of the length 9:

byte[] bytes = new byte[8+1];
bytes[0] = 1; // 0x01 0x00 0x00 0x00 .... 0x00
BigInteger base = new BigInteger(bytes);

And then you can add any random BigInteger you like with the BigInteger(int, Random); constructor.

BigInteger r = new BigInteger(32, new Random());
System.out.println(base);
System.out.println(r);
System.out.println(base.add(r));

This will generate an outlike like this:

18446744073709551616
1629299848
18446744075338851464

Generating random unique BigIntegers within a specified range?

There is a built-in method to generate a random BigInteger between 0 and 2^n - 1.

You can use that in a loop to generate numbers up to 2^80.

The chance that a number will fall below 2^70 is very small ( ~ 0.1%). If that happens (and with 500 iterations it might very well), just draw another one.

This will give you a uniform distribution of random numbers between 2^70 and 2^80.

The chance that a number will repeat is almost nonexistent. If you feel that it cannot be ignored, check your previous numbers for duplicates, and draw again.

Does anyone know how to generate a number within specific bits in Java?

New answer:

The BigInteger class has a constructor that you can use to generate a random number with the given number of bits. This is how you could use it:

BigInteger random(int bits) {
Random random = new Random();
return new BigInteger(bits, random);
}

Old answer with a long-winded way of doing the same:

The java.util.Random class has a nextBytes method to fill an array of bytes with random values. You can use that to generate a BigInteger with an arbitrary number of bytes.

The complication is, what to do when number of bits isn't a multiple of 8? My suggestion is to generate one byte too much and get rid of the extra bits with a shift operation.

BigInteger random(int bits) {
Random random = new Random();
// One byte too many if not multiple of 8
byte[] bytes = new byte[(bits + 7) / 8];
random.nextBytes(bytes);
BigInteger randomNumber = new BigInteger(1, bytes);
// Get rid of extra bits if not multiple of 8
return randomNumber.shiftRight(bytes.length*8 - bits);
}

How to choose a random number in the range when working with BigInteger

You can generate a random double in the closed range [x1,x2] like this [1]:

double f = Math.random()/Math.nextDown(1.0);
double x = x1*(1.0 - f) + x2*f;

Using BigDecimals with the range between 2 and bigInteger-2;:

double f = Math.random()/Math.nextDown(1.0);
BigDecimal.valueOf(2).multiply(BigDecimal.valueOf(1.0 - f)).add(new BigDecimal(bigInteger.subtract(BigInteger.valueOf(2))).multiply(BigDecimal.valueOf(f))).toBigInteger()

Generating Random Numbers from 1 to n-1 for BigIntegers in Java

May this work

    public static void main(String[] args) {
BigInteger bigInteger = new BigInteger("9349988899999");
BigInteger bigInteger1 = bigInteger.subtract(new BigInteger("1"));
System.out.println(randomBigInteger(bigInteger1));
}

public static BigInteger randomBigInteger(BigInteger n) {
Random rnd = new Random();
int maxNumBitLength = n.bitLength();
BigInteger aRandomBigInt;
do {
aRandomBigInt = new BigInteger(maxNumBitLength, rnd);
// compare random number lessthan ginven number
} while (aRandomBigInt.compareTo(n) > 0);
return aRandomBigInt;
}


Related Topics



Leave a reply



Submit