Miller-Rabin算法

Posted antigonae

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Miller-Rabin算法相关的知识,希望对你有一定的参考价值。

写在前面:

  记录了个人的学习过程,同时方便复习

  整理自网络

  非原创部分会标明出处

 

技术分享图片

by blackgryph0n

 

目录

 

 

结论

  Miller-Rabin算法可以在O(k log2(n))的时间内检测一个超级大的正整数n是否是素数,k为自己设定的检测的次数

 

证明

  [?]费马-欧拉定理

  对于任意素数p,以及对于模p的剩余类环{1,2,...,p-1}中的任意数x,都满足xp ≡ x (mod p)

  [?]快速幂

  p是素数为xp ≡ x (mod p)的充分不必要条件

  但是仍然可以用这个技巧来排除大量的合数

  为了排除大量合数,我们需要从模p的剩余类环中选取更多的数进行测试,以增强结果的可信度,即二次探测定理,只要存在一个数x不满足xp ≡ x (mod p),那么p就绝不可能是素数

 

拓展

  然而某些合数模p的剩余类环中,对于任意1,..,p-1中的x都满足xp ≡ x (mod p),这类合数称为卡迈克尔(Carmichael)数

  Carmichael数是比较少的,在1~100000000范围内的整数中,只有255个

  In number theory, a Carmichael number is a composite number n which satisfies the modular arithmetic congruence relation bn-1 ≡ 1 (mod n) for all integers b which are relatively prime to n

 

  They are named for Robert Carmichael. The Carmichael numbers are the subset K1 of the Kn?del numbers

  Equivalently, a Carmichael number is a composite number bn ≡ b (mod n) for which  for all integers b

——Wikipedia

 

常见卡迈克尔数:

561

1105

1729

2465

2821

6601

8911

10585

15841

……

——bia度百科

  裸的Miller-Rabin算法不能够筛除这样的合数

 

实现

上代码:

C++:

 1 #include<bits/stdc++.h>
 2 
 3 using namespace std;
 4 typedef long long ll;
 5 
 6 int const times=10;
 7 
 8 ll ponyFE(ll a,ll b,ll c)
 9 {
10     ll ans=1;
11     a%=c;
12     while(b!=0)
13     {
14         if(b&1) ans=(ans*a)%c;
15         b>>=1;
16         a=(a*a)%c;
17     }
18     return ans;
19 }
20 
21 bool millerRabin(ll x)
22 {
23     if(x==2) return 1;
24     if(!(x&1)||x==1) return 0;
25     
26     ll d=x-1,m;
27     while(!(d&1)) d>>=1;ll tmp=d;
28     for(int i=1;i<=times;++i)
29     {
30         d=tmp;
31         
32         m=ponyFE(rand()%(x-2)+2,d,x);
33         if(m==1) goto ok;
34         else for(;d<x&&d>=0;m=(m*m)%x,d<<=1)
35             if(m==x-1) goto ok;
36             
37         return 0;
38         ok:{}
39     }
40     
41     return 1;
42 }
43 
44 int main(int argc,char *argv[],char *enc[])
45 {
46     int tot=0;
47     for(ll i=1;i<=100;++i)
48         if(millerRabin(i)) printf("%d
",i),++tot;    
49     printf("tot:%d
",tot);
50     
51     return 0;
52 }

Java:

  

以上是关于Miller-Rabin算法的主要内容,如果未能解决你的问题,请参考以下文章

浅谈Miller-Rabin素数检测算法

Miller-Rabin?素数测试算法

Miller-Rabin素性判定算法

Miller-Rabin算法

@总结 - 10@ Miller-Rabin素性测试与Pollard-Rho因数分解

Miller-Rabin素数检测算法