首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > JAVA > Java相关 >

rsa算法中找寻素数的概率测试算法

2013-06-25 
rsa算法中寻找素数的概率测试算法用java 写的算法,是关于rsa中寻找素数的一个概率性测试算法???????????[

rsa算法中寻找素数的概率测试算法
用java 写的算法,是关于rsa中寻找素数的一个概率性测试算法???????????
[解决办法]
是不是这个

SecureRandom sr = SecureRandom.getInstance("SHA1PRNG");

[解决办法]
RSA 中寻找素数?RSA 的公私钥都是由两个大素数生成的,不是很明白你提问的目的。

素性测试可以使用 Miller-Rabin 素性测试,写了段代码,供为参数:

public class MillerRabin {

    public static void main(String[] args) {
        long t0, t1;
        t0 = System.nanoTime();
        boolean b = !isComposite(479001599);
        boolean c = !isComposite(456789012);
        t1 = System.nanoTime();
        System.out.println(t1 - t0);
        System.out.println(b + " " + c);
    }

    /**
     * <p>Miller-Rabin 测试某一个数是否是合数</p>
     *
     * @param n 需要测试的数
     * @return true: 该数为合数;false: 该数为素数
     */
    public static boolean isComposite(int n) {
        if (n < 2) {
            throw new IllegalArgumentException("number must greater than or equals 2");
        }
        // 排除 2、3、5、7 以加速测试
        if (n == 2 
[解决办法]
 n == 3 
[解决办法]
 n == 5 
[解决办法]
 n == 7) {
            return false;
        }

        // 偶数
        if ((n & 1) == 0) {
            return true;
        }

        // 排除 3、5、7 的倍数,以加速测试
        if (n % 3 == 0) {


            return true;
        }
        if (n % 5 == 0) {
            return true;
        }
        if (n % 7 == 0) {
            return true;
        }

        // 寻找 s 和 d 以满足 n = 2^s * d + 1
        int s = 0, d = n - 1;
        while ((d & 1) == 0) {
            d >>= 1;
            s++;
        }

        // 对于各种数值需要进行 Miller-Rabin 基准测试的素数值
        // 参考:http://en.wikipedia.org/wiki/Miller%E2%80%93Rabin_primality_test#Deterministic_variants_of_the_test
        // if n < 1,373,653, it is enough to test a = 2 and 3;
        // if n < 9,080,191, it is enough to test a = 31 and 73;
        // if n < 4,759,123,141, it is enough to test a = 2, 7, and 61;
        // if n < 2,152,302,898,747, it is enough to test a = 2, 3, 5, 7, and 11;
        // if n < 3,474,749,660,383, it is enough to test a = 2, 3, 5, 7, 11, and 13;
        // if n < 341,550,071,728,321, it is enough to test a = 2, 3, 5, 7, 11, 13, and 17.

        if (n < 1373653) {
            if (loopMillerRabin(s, d, n, 2, 3)) {
                return true;
            }
        } else if (n < 9080191) {
            if (loopMillerRabin(s, d, n, 31, 73)) {
                return true;
            }
        } else {
            // 4,759,123,141 已经超过 int 的最大值,因此大于等于 9080191 就采用 4,759,123,141 的基准测试
            if (loopMillerRabin(s, d, n, 2, 7, 61)) {


                return true;
            }
        }
        return false;
    }

    /**
     * <p>循环 Miller-Rabin 测试</p>
     *
     * @param s n = 2^s * d + 1 中的 s 值
     * @param d n = 2^s * d + 1 中的 d 值
     * @param n 需要测试的数
     * @param t 测试的基准素数
     */
    private static boolean loopMillerRabin(int s, int d, int n, int... t) {
        for (int i = 0; i < t.length; i++) {
            if (testMillerRabin(t[i], s, d, n)) {
                return true;
            }
        }
        return false;
    }

    /**
     * <p>Miller-Rabin 基本测试</p>
     *
     * @param a 素性测试基准素数
     * @param s n = 2^s * d + 1 中的 s 值
     * @param d n = 2^s * d + 1 中的 d 值
     * @param n 需要测试的数
     * @return 测试某一数是否是合数。true: 该数是合数;false: 该数可能是素数。若返回 false
     * 需要进行多基准的联合测试才能判断该数确实是素数
     */
    private static boolean testMillerRabin(int a, int s, int d, int n) {
        if (montgomery(a, d, n) != 1) {
            int e = 1;
            for (int i = 0; i < s; i++) {
                if (montgomery(a, d * e, n) + 1 == n) {
                    return false;
                }
                e <<= 1;
            }
            return true;
        }
        return false;
    }

    /**
     * <p>使用 Montgomery 算法计算 (base ^ exp) % mod 的值。</p>


     * 
     * <p>由于 Java 中 int 的运算速度远远大于 long 的运算速度,因此该算法需要改进!</p>
     *
     * @param base 基数
     * @param exp 指数
     * @param mod 模数
     */
    private static int montgomery(int base, int exp, int mod) {
        if (base > 46340 
[解决办法]
 mod > 46340) {
            long temp = 1;
            long prod = base % mod;
            while (exp > 1) {
                if ((exp & 1) != 0) {
                    temp = (temp * prod) % mod;
                }
                prod = (prod * prod) % mod;
                exp >>= 1;
            }
            return (int) ((temp * prod) % mod);
        } else {
            int temp = 1;
            int prod = base % mod;
            while (exp > 1) {
                if ((exp & 1) != 0) {
                    temp = (temp * prod) % mod;
                }
                prod = (prod * prod) % mod;
                exp >>= 1;
            }
            return (temp * prod) % mod;
        }
    }

    /**
     * <p>
     * 根据复化辛普生法则计算高斯 Li 函数。Li(x) 近似于素数个数函数 π(x)
     * </p>
     * 
     * @param x 数值范围
     * @return 该值以内的素数个数的估计值
     */
    private static double gaussLi(int x) {


        int n = x;
        double s = 2;
        double h = (x - s) / n;
        double a = f(s + h / 2);
        double b = 0;
        for (int k = 1; k < n; k++) {
            a += f(s + k * h + h / 2);
            b += f(s + k * h);
        }
        return (h / 6) * (f(s) + 4 * a + 2 * b + f(x));
    }

    /**
     * <p>
     * Guass Li(x) 积分函数项
     * </p>
     * 
     * @param x
     * @return
     */
    private static double f(double x) {
        return 1 / Math.log(x);
    }
}



热点排行