质数测试
今天我来填坑了,之前我在数学基础算法——质数篇这篇文章中提到我要单独讲一下MillerRabin算法,最近已经有许多粉丝在催了,所以我马不停蹄的来出这篇文章了,顺便把Fermat素数测试也讲了,因为想要学会 MillerRabin 算法,我们必须要先了解 Fermat算法的问题。
Fermat 素数测试
简介
Fermat prime teat (费马素性检验)是一种素数判定法则,利用随机化算法判断一个数是合数还是可能是素数。但是这样有可能会错。
思路
对于Fermat 素数测试,我们要先知道一个数学上的定理:费马小定理
费马小定理:如果 p p p 是一个素数,且整数 a a a 不是 p p p 的倍数,则 a p − 1 ≡ 1 ( m o d p ) a^{p-1} ≡ 1 (modp) ap−1≡1(modp)
根据这个结论,我们又可以稍微转换一下,将其改为 “如果 p p p 是一个素数,且整数 a a a 为一个小于 p p p 且不等于 0 的一个数,则 a p − 1 ≡ 1 ( m o d p ) a^{p-1} ≡ 1 (modp) ap−1≡1(modp)”
那么我们就可以知道,当有一个数 a a a 使得 a p − 1 ≢ 1 ( m o d p ) a^{p-1} \not\equiv 1 (modp) ap−1≡1(modp) 则 p p p 一定不是质数。
若我们要检验 n n n 是不是质数,那么我们就可以不断选取范围在 2 → n − 1 2 \to n-1 2→n−1 中的基数 a a a ,并且检验是否每次都有 a n − 1 ≡ 1 ( m o d n ) a^{n-1} \equiv 1(mod n) an−1≡1(modn) 就行了。
代码实现
int quickpow(int a,int b,int x){
if (b==0)return 1;
int tmp=quickpow(a,b/2,x)%x;
tmp=tmp*tmp%x;
if (b%2==1)tmp*=a%x;
return tmp%x;
}
bool Fermat(int n){
if (n<3)return n==2;
for (int i=1;i<=log2(n);i++){
int a=rand()%(n-2)+2;
if (quickpow(a,n-1,n)!=1){
return false;
}
}
return true;
}
但是这样的测试在遇到一些特殊的数的时候,会错,也就是说满足 a n − 1 ≡ 1 ( m o d n ) a^{n-1} \equiv 1(mod n) an−1≡1(modn) 的 n n n 不一定是素数,则这些数被称为以 a a a 为底的伪素数。
也就是说,费马小定理的逆定理并不成立,而其中所有与 n n n 互质的正整数 b b b ,都有同余式 b n − 1 ≡ ( m o d n ) b^{n-1} \equiv (mod n) bn−1≡(modn) 成立,则称合数 n n n 为 Carmichael 数,也就是卡迈克尔数。其中最小的一个卡迈克尔数是 561 。
MillerRabin 素数测试
简介
Miller-Rabin prime test(米勒-拉宾素性检验)是一种素数判定法则,利用随机化算法判断一个数是合数还是可能是素数。卡内基梅隆大学的计算机系教授Gary Lee Miller首先提出了基于广义黎曼猜想的确定性算法,由于


3168

被折叠的 条评论
为什么被折叠?



