zoukankan      html  css  js  c++  java
  • [学习笔记]Miller-Rabin素数检测

    [学习笔记]Miller-Rabin素数检测

    一.什么是Miller-Rabin

    ​ miller-rabin是一个用来检验一个数是不是素数的算法,速度非常的快,(O(log^2n))(加了快速加法)

    二.费马小定理

    ​ 对于素数p,有

    [a^pequiv a;(mod; p) ]

    ​ 这是费马小定理的基本形式。可以变形成为(a^{p-1}equiv1(mod;p))。对于费马小定理来说,大多数时候满足这个式子的一个自然数是一个质数,当然有满足却不是质数的情况。并且不满足他的一定不是质数,这是Miller-Rain算法的基本原理。也就是说,当我们用多个底数a检验一个自然数,发现都满足费马小定理,我们就大约可以认定他是一个质数。

    ​ 对于这样的一类数p(以561为代表):(forall;ain Z,a^{p-1}equiv1(mod;p)),我们称它为Carmichael数,普通的Miller-Rabin是会将他们误判为素数的。

    三.二次探测定理

    ​ 对于一个奇素数(除2以外的素数)来说,一个方程(x^2equiv1(mod;p))的解为(xequiv1(mod;p))(xequiv p-1(mod;p))

    ​ 证:

    [egin{align} x^2equiv1(mod;p)\ x^2-1equiv0(mod;p)\ (x+1)(x-1)equiv0(mod;p) end{align} ]

    ​ 于是对于一个p-1为偶数的指数来说,我们就先把它用二次探测定理做一遍。令(u=frac{p-1}{2}),对(a^uequiv1(mod;p)),(a^uequiv p-1(mod;p)),进行判定。

    四.后记

    ​ 以上的两种方法结合起来应该就可以进行正确的检验素数,但然也可以先把几个常用的素数:2,3,5...17等先判定一遍以此来减小出错概率(笔者还没有测过)

    ​ 对于比较大的数据,乘法(x^2)可能会出现溢出,于是要打一个快速加来模仿乘法。

    五.代码

    #define m_for(i,a,b) for(int i=(a);i<=(b);++i)
    #define ll long long
    const int times=10;
    ll multi(ll a,ll b,ll m)
    {
        ll ans=0%m;
        while(b)
        {
            if(b&1)ans=(ans+a)%m,b--;
            b >>= 1;
            a=(a+a)%m;
        }
        return ans;
    }
    ll KSM(ll a,ll b,ll m)
    {
        ll ans=1%m;
        while(b)
        {
            if(b&1)ans=multi(ans, a, m),b--;
            b>>=1;
            a=multi(a,a,m);
        }
        return ans;
    }
    inline bool Miller_Rabin(ll p){
    	if(p<=2)return p==2;
    	if(!(p&1))return 0;
    	ll u=p-1;
    	int power=0;
    	while(!(u&1))u>>=1,power++;
    	m_for(i,1,times){
    		ll a=rand()%(p-2)+2,x=KSM(a,u,p),y;
    		for(int i=1;i<=power;++i,x=y){
    			if((y=multi(x,x,p))==1&&x!=1&&x!=p-1)return 0;
    		}
    		if(x!=1)return 0;
    	}
    	return 1;
    }
    
  • 相关阅读:
    tee命令
    linux优化之SElinux关闭
    (1)使用bash脚本实现批量添加用户
    Django admin管理工具的使用、定制及源码解析
    Mysql常见命令
    树梅派
    19道Python循环遍历,while,for语句测试题,网上看到的题目,自己不看答案全部做了一次,总共3个小时左右
    9*9的矩形,中间有个星号,按不同方向键,星星对应移动
    app在admin中显示成我们想要的中文名
    九九乘法表
  • 原文地址:https://www.cnblogs.com/clockwhite/p/12148877.html
Copyright © 2011-2022 走看看