Skip to content

Commit 13be044

Browse files
authored
Merge pull request #166 from NarenCK11/eulerpseudoprime
Added Euler Pseudoprime Problem in Java
2 parents dabc7b0 + d6cb6e4 commit 13be044

1 file changed

Lines changed: 98 additions & 0 deletions

File tree

Java/maths/EulerPseudoprime.java

Lines changed: 98 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,98 @@
1+
import java.math.BigInteger;
2+
import java.util.Random;
3+
4+
public final class EulerPseudoprime {
5+
6+
private EulerPseudoprime() {}
7+
8+
private static final Random RANDOM = new Random();
9+
10+
public static boolean isProbablePrime(BigInteger n, int trials) {
11+
if (n.compareTo(BigInteger.TWO) < 0) {
12+
return false;
13+
}
14+
if (n.equals(BigInteger.TWO) || n.equals(BigInteger.valueOf(3))) {
15+
return true;
16+
}
17+
if (n.mod(BigInteger.TWO).equals(BigInteger.ZERO)) {
18+
return false;
19+
}
20+
21+
for (int i = 0; i < trials; i++) {
22+
BigInteger a = uniformRandom(BigInteger.TWO, n.subtract(BigInteger.TWO));
23+
BigInteger jacobi = BigInteger.valueOf(jacobiSymbol(a, n));
24+
25+
if (jacobi.equals(BigInteger.ZERO)) {
26+
return false;
27+
}
28+
29+
BigInteger exp = n.subtract(BigInteger.ONE).divide(BigInteger.TWO);
30+
BigInteger modExp = a.modPow(exp, n);
31+
32+
if (!modExp.equals(jacobi.mod(n))) {
33+
return false;
34+
}
35+
}
36+
return true;
37+
}
38+
39+
public static int jacobiSymbol(BigInteger a, BigInteger n) {
40+
if (n.signum() <= 0 || n.mod(BigInteger.TWO).equals(BigInteger.ZERO)) {
41+
throw new IllegalArgumentException("n must be a positive odd integer.");
42+
}
43+
44+
int result = 1;
45+
a = a.mod(n);
46+
47+
while (a.compareTo(BigInteger.ZERO) != 0) {
48+
while (a.mod(BigInteger.TWO).equals(BigInteger.ZERO)) {
49+
a = a.divide(BigInteger.TWO);
50+
BigInteger nMod8 = n.mod(BigInteger.valueOf(8));
51+
if (nMod8.equals(BigInteger.valueOf(3)) || nMod8.equals(BigInteger.valueOf(5))) {
52+
result = -result;
53+
}
54+
}
55+
56+
BigInteger temp = a;
57+
a = n;
58+
n = temp;
59+
60+
if (a.mod(BigInteger.valueOf(4)).equals(BigInteger.valueOf(3)) && n.mod(BigInteger.valueOf(4)).equals(BigInteger.valueOf(3))) {
61+
result = -result;
62+
}
63+
a = a.mod(n);
64+
}
65+
return n.equals(BigInteger.ONE) ? result : 0;
66+
}
67+
68+
private static BigInteger uniformRandom(BigInteger min, BigInteger max) {
69+
BigInteger result;
70+
do {
71+
result = new BigInteger(max.bitLength(), RANDOM);
72+
} while (result.compareTo(min) < 0 || result.compareTo(max) > 0);
73+
return result;
74+
}
75+
76+
public static void main(String[] args) {
77+
// Define the numbers to test and the number of trials for the test.
78+
int trials = 20;
79+
String[] testNumbers = {
80+
"7", // Small prime
81+
"10", // Small even composite
82+
"91", // Small odd composite
83+
"563", // A known prime number
84+
"1105", // An Euler pseudoprime to base 2
85+
"294409", // A larger prime number
86+
"294411" // A larger composite number
87+
};
88+
89+
System.out.printf("Running Euler Primality Test with %d trials...%n%n", trials);
90+
91+
for (String numStr : testNumbers) {
92+
BigInteger n = new BigInteger(numStr);
93+
boolean isPrime = isProbablePrime(n, trials);
94+
String result = isPrime ? "Probably Prime" : "Composite";
95+
System.out.printf("Is %s prime? --> %s%n", n, result);
96+
}
97+
}
98+
}

0 commit comments

Comments
 (0)