zoukankan      html  css  js  c++  java
  • 米勒罗宾素性测试算法简介+模板(转)

    看了一些别人的博客,发现里面涉及到的公式没有证明,于是就打算自己写一篇比较详细的讲解。

    先看两个引理及其证明(建议把证明搞懂)。

    PS:以下图片均为原作者用wps制作,如想使用请附上作者博客链接,谢谢O(∩_∩)O。

    看完了上面的引理,那就可以正式开始Miller-Rabin算法的讲解了。

    背景:

    素性测试(即测试给定的数是否为素数)是近代密码学中的一个非常重要的课题。虽然Wilson定理(对于给定的正整数n,n是素数的充要条件为)给出了一个数是素数的充要条件,但根据它来素性测试所需的计算量太大,无法实现对较大整数的测试。目前,尽管高效的确定性的素性算法尚未找到,但已有一些随机算法可用于素性测试及大整数的因数分解。下面描述的Miller-Rabin素性测试算法就是一个这样的算法。

    算法:

    首先要知道费马定理只是n是素数的必要条件。即费马定理不成立,n一定是合数;费马定理成立,n可能是素数。接下来请看Miller-Rabin算法的分析过程。

    附上代码模板:

    // 18位素数:154590409516822759
    // 19位素数:2305843009213693951 (梅森素数)
    // 19位素数:4384957924686954497
    LL prime[6] = {2, 3, 5, 233, 331};
    LL qmul(LL x, LL y, LL mod) { // 乘法防止溢出, 如果p * p不爆LL的话可以直接乘; O(1)乘法或者转化成二进制加法
     
     
        return (x * y - (long long)(x / (long double)mod * y + 1e-3) *mod + mod) % mod;
        /*
    	LL ret = 0;
    	while(y) {
    		if(y & 1)
    			ret = (ret + x) % mod;
    		x = x * 2 % mod;
    		y >>= 1;
    	}
    	return ret;
    	*/
    }
    LL qpow(LL a, LL n, LL mod) {
        LL ret = 1;
        while(n) {
            if(n & 1) ret = qmul(ret, a, mod);
            a = qmul(a, a, mod);
            n >>= 1;
        }
        return ret;
    }
    bool Miller_Rabin(LL p) {
        if(p < 2) return 0;
        if(p != 2 && p % 2 == 0) return 0;
        LL s = p - 1;
        while(! (s & 1)) s >>= 1;
        for(int i = 0; i < 5; ++i) {
            if(p == prime[i]) return 1;
            LL t = s, m = qpow(prime[i], s, p);
            while(t != p - 1 && m != 1 && m != p - 1) {
                m = qmul(m, m, p);
                t <<= 1;
            }
            if(m != p - 1 && !(t & 1)) return 0;
        }
        return 1;
    }
    

     原文链接:算法讲解

    模板链接:模板链接

  • 相关阅读:
    js 数据类型的转换
    js数组学习方法汇总
    跳转页面的方法总结
    今天用js做拉一个时钟
    今天用js做拉一个时钟
    js中字符的比较
    1005 继续(3n+1)猜想 (25分)
    1002 写出这个数
    日期差值
    1040 有几个PAT (25分)
  • 原文地址:https://www.cnblogs.com/Staceyacm/p/10781909.html
Copyright © 2011-2022 走看看