1. 程式人生 > >米勒拉賓大素數生成演算法

米勒拉賓大素數生成演算法

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;
    }
}