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算法的主要内容,如果未能解决你的问题,请参考以下文章