zoukankan      html  css  js  c++  java
  • 理解Miller-Rabbin算法

    转自:http://www.dxmtb.com/blog/miller-rabbin/

    普通的素数测试我们有O(√ n)的试除算法。事实上,我们有O(slog³n)的算法。

    定理一:假如p是质数,且(a,p)=1,那么a^(p-1)≡1(mod p)。即假如p是质数,且a,p互质,那么a的(p-1)次方除以p的余数恒等于1。(费马小定理)

    该定理的逆命题是不一定成立的,但是令人可喜的是大多数情况是成立的。

    于是我们就得到了一个定理的直接应用,对于待验证的数p,我们不断取a∈[1,p-1]且a∈Z,验证a^(p-1) mod p是否等于1,不是则p果断不是素数,共取s次。其中a^(p-1) mod p可以通过把p-1写成二进制,由(ab)mod c=(a mod c)b mod c,可以在t=log(p-1)的时间内计算出解,如考虑整数相乘的复杂度,则一次计算的总复杂度为log³(p-1)。这个方法叫快速幂取模。

    为了提高算法的准确性,我们又有一个可以利用的定理。 定理二:对于0<x<p,x^2 mod="" p="1" ==""> x=1或p-1。

    我们令p-1=(2^t)*u,即p-1为u二进制表示后面跟t个0。我们先计算出x[0]=a^u mod p ,再平方t次并在每一次模p,每一次的结果记为x[i],最后也可以计算出a^(p-1) mod p。若发现x[i]=1而x[i-1]不等于1也不等于p-1,则发现p果断不是素数。

    可以证明,使用以上两个定理以后,检验s次出错的概率至多为2^(-s),所以这个算法是很可靠的。

    需要注意的是,为了防止溢出(特别大的数据),a*b mod c 也应用类似快速幂取模的方法计算。当然,数据不是很大就可以免了。

     1 typedef unsigned long long LL;
     2 
     3 LL modular_multi(LL x,LL y,LL mo)
     4 {
     5     LL t;
     6     x%=mo;
     7     for(t=0;y;x=(x<<1)%mo,y>>=1)
     8         if (y&1)
     9             t=(t+x)%mo;
    10     return t;
    11 }
    12 
    13 LL modular_exp(LL num,LL t,LL mo)
    14 {
    15     LL ret=1,temp=num%mo;
    16     for(;t;t>>=1,temp=modular_multi(temp,temp,mo))
    17         if (t&1)
    18             ret=modular_multi(ret,temp,mo);
    19     return ret;
    20 }
    21 
    22 bool miller_rabbin(LL n)
    23 {
    24     if (n==2)return true;
    25     if (n<2||!(n&1))return false;
    26     int t=0;
    27     LL a,x,y,u=n-1;
    28     while((u&1)==0) t++,u>>=1;
    29     for(int i=0;i<S;i++)
    30     {
    31         a=rand()%(n-1)+1;
    32         x=modular_exp(a,u,n);
    33         for(int j=0;j<t;j++)
    34         {
    35             y=modular_multi(x,x,n);
    36             if (y==1&&x;!=1&&x;!=n-1)
    37                 return false;
    38             x=y;
    39         }
    40         if (x!=1)
    41             return false;
    42     }
    43     return true;
    44 }
  • 相关阅读:
    ASP.NET中JSON的序列化和反序列化
    Git 本地项目上传至托管平台(OsChina/GitHub)
    Android Gradle 完整指南(转)
    开发错误记录13:java.lang.UnsatisfiedLinkError: Couldn't load xxx.so: findLibrary returned null
    Android其它新控件 (转)
    一个Activity掌握Design新控件 (转)
    一个Activity掌握Android5.0新控件 (转)
    一个Activity掌握Android4.0新控件 (转)
    开发错误日记 12: Unsupported major.minor version 52.0
    Linux 下各个目录的作用及内容
  • 原文地址:https://www.cnblogs.com/pter/p/5703380.html
Copyright © 2011-2022 走看看