米勒拉賓大素數生成演算法
阿新 • • 發佈:2019-01-01
package password;
import java.math.BigInteger;
public class BigPrime {
public BigInteger p;
static int[] smallprime = new int[1229];
public BigPrime() {
// TODO Auto-generated constructor stub
}
// 找到1000以內的1229個素數,並且存在陣列內。
public static int[] FindSmallPrime() throws Exception {
int j = 2;
int k = 0;
for (int i = 2; i < 10000; i++) {
for (j = 2; j < Math.sqrt(i) + 1; j++) {
if (i % j == 0) {
break;
} else {
continue;
}
}
if (j > Math.sqrt(i)) {
smallprime[k] = i;
k++;
}
}
return smallprime;
}
// 生成一個n位奇數。
public void CreateBigInterger(int n) throws Exception {
String str = null;
int[] m = new int[n];
for (int i = 0; i < n; i++) {
m[i] = (int) (Math.random() * 10);
}
if (m[0] == 0) {
m[0] = 1;
}
if (m[m.length - 1] % 2 == 0) {
m[m.length - 1] = m[m.length - 1] + 1;
}
for (int i = 0; i < m.length; i++) {
str = str + m[i];
}
str = str.substring(4);
p = new BigInteger(str);
// p=BigInteger.valueOf(Integer.parseInt(str));
}
// 判斷n位奇數能不能被數組裡面的素數整除。
public BigInteger TestPrime() throws Exception {
for (int i = 0; i < smallprime.length; i++) {
String str = String.valueOf(smallprime[i]);
BigInteger b = BigInteger.valueOf(Integer.parseInt(str));
if (b.compareTo(BigInteger.ZERO) == 0) {
continue;
} else if (BigInteger.ZERO.compareTo(p.remainder(b)) != 0) {
p = p.add(BigInteger.valueOf(2));
this.TestPrime();
}
}
return p;
}
public static BigInteger CreatePrime(int n) throws Exception {
BigPrime bp = new BigPrime();
bp.CreateBigInterger(n);
bp.TestPrime();
while (!MillerRabin.Miller_Rabin(bp.p)) {
bp.p = bp.p.add(BigInteger.valueOf(2));
}
System.out.println(bp.p);
return bp.p;
}
}
米勒拉賓演算法如下:
package password;
import java.math.BigInteger;
import java.util.Random;
public class MillerRabin {
public static final int Times = 10;
public static BigInteger quick_mod(BigInteger a, BigInteger b, BigInteger m) {
BigInteger ans = BigInteger.ONE;
a = a.mod(m);
while (!(b.equals(BigInteger.ZERO))) {
if ((b.mod(BigInteger.valueOf(2))).equals(BigInteger.ONE)) {
ans = (ans.multiply(a)).mod(m);
b = b.subtract(BigInteger.ONE);
}
b = b.divide(BigInteger.valueOf(2));
a = (a.multiply(a)).mod(m);
}
return ans;
}
public static boolean Miller_Rabin(BigInteger n) {
if (n.equals(BigInteger.valueOf(2)))
return true;
if (n.equals(BigInteger.ONE))
return false;
if ((n.mod(BigInteger.valueOf(2))).equals(BigInteger.ZERO))
return false;
BigInteger m = n.subtract(BigInteger.ONE);
BigInteger y = BigInteger.ZERO;
int k = 0;
while ((m.mod(BigInteger.valueOf(2))).equals(BigInteger.ZERO)) {
k++;
m = m.divide(BigInteger.valueOf(2));
}
Random d = new Random();
for (int i = 0; i < Times; i++) {
int t = 0;
if (n.compareTo(BigInteger.valueOf(10000)) == 1) {
t = 10000;
} else {
t = n.intValue() - 1;
}
int a = d.nextInt(t) + 1;
BigInteger x = quick_mod(BigInteger.valueOf(a), m, n);
for (int j = 0; j < k; j++) {
y = (x.multiply(x)).mod(n);
if (y.equals(BigInteger.ONE) && !(x.equals(BigInteger.ONE))
&& !(x.equals(n.subtract(BigInteger.ONE))))
return false;
x = y;
}
if (!(y.equals(BigInteger.ONE)))
return false;
}
return true;
}
}