Alexandre Girard
Alexandre Girard

Reputation: 5

Generating two prime numbers of a certain size that are not equal

I have a loop to generate two prime numbers, I don't want them to be equal and they both need to be exactly exactly "digits" digits. I can get the first prime number (bigInt1) to be of required length, but the second one (bigInt2) varies from "digits" to "digits + 1" and I have no idea why, I have spent many hours looking at this code and I just can't find a solution, can anyone help?

...
public static BigInteger[] bigInts = new BigInteger[2];
static int digits;


public static void GeneratePrimeBigInt(String stringDigits){

    digits = Integer.parseInt(stringDigits);
    int bits = (int)Math.ceil(Math.log(Math.pow(10,digits))/(Math.log(2))); // convert digits to bits

    // Generate Huge prime Random Number with 1 - 2^(-1000) probability of being prime
    BigInteger bigInt1 = new BigInteger(bits,1000,new Random(System.currentTimeMillis()));
    BigInteger bigInt2 = new BigInteger(bits,1000,new Random(System.currentTimeMillis()));

    while (bigInt1.toString().length() != digits){
        bigInt1 = new BigInteger(bits,1000,new Random(System.currentTimeMillis()));
        }


    // make sure no two bigIntegers are the same
    while(bigInt1.equals(bigInt2)){
        BigInteger bigInt21 = new BigInteger(bits,1000,new Random(System.currentTimeMillis()));
        bigInt2 = bigInt21;
        if ((bigInt2.toString().length()) != digits){
            while (bigInt2.toString().length() != digits){
                BigInteger bigInt22 = new BigInteger(bits,1000,new Random(System.currentTimeMillis()));
                bigInt2 = bigInt22;
            }
        }
    }

    // store results in array for future reference and display results in RsaWindow 
    RsaWindow.setMyLabels(5, "Here are two prime numbers, p and q, 
            of " + digits + "digits");
    bigInts[0] = bigInt1;
    RsaWindow.setMyLabels(7,"p= " + bigInt1.toString());
    bigInts[1] = bigInt2;
    RsaWindow.setMyLabels(8,"q= " + bigInt2.toString());
}

Upvotes: 0

Views: 678

Answers (3)

vinay
vinay

Reputation: 960

The problem is with this line :

while(bigInt1.equals(bigInt2))

"check for bigInt2 validity is done after the while statement". So few test cases are missed. The above condition is also true for both prime numbers which are of different no of digits. Suggestion is to check bigInt2 digits before checking "bigInt1.equals(bigInt2)" and it will always work.

Upvotes: 0

Jk1
Jk1

Reputation: 11443

The following code in my tests gives the results of a correct length:

private static SecureRandom random = new SecureRandom();

public static void generatePrimeBigInt(String stringDigits) {
    int digits = Integer.parseInt(stringDigits);
    int bits = (int) Math.floor(Math.log(Math.pow(10, digits)) / (Math.log(2)));
    BigInteger bigInt1 = BigInteger.ZERO;
    BigInteger bigInt2 = BigInteger.ZERO;
    while (bigInt1.equals(bigInt2)){
        bigInt1 = new BigInteger(bits, 1000, random);
        bigInt2 = new BigInteger(bits, 1000, random);
    }
    //numbers are ready to store or other use at this point
}

Upvotes: 1

blgt
blgt

Reputation: 8205

The constructor for BigInteger uses length in bits. That is not necessarily the same number of decimal digits every time you convert a new number from binary to decimal.

[EDIT] What I said before made no sense. Fixed.

A possible solution is to get rid of the if, and add it to the first while loop:

while (bigInt1.equals(bigInt2) || bigInt2.toString().length() != digits)

However this seems like a really heavyweight piece of code. What exactly are you trying to accomplish?

Upvotes: 2

Related Questions