Reputation: 5
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
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
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
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