费马小定律介绍(基础)
p为素数,对于任意的正整数a,均有
如果a不是p的倍数,这个定理也可以写成
同余性质(用于证明费马小定律)
性质:如果a≡b(mod m),x≡y(mod m),则a+x≡b+y(mod m)。
如果a≡b(mod m),x≡y(mod m),则ax≡by(mod m)。
如果ac≡bc(mod m),且c和m互质,则a≡b(mod m) (就是说同余式两边可以同时除以一个和模数互质的数)。
费马小定律的证明
,考虑
共
个数,将它们分别除以p,余数分别为
,则集合{r1,r2,r3,...,rp-1}为集合{1,2,3,...,(p-1)}的重新排列,即1,2,3,....,(p-1)在余数中恰好各出现一次;这是因为对于任两个相异k*a而言(k=1,2,3....(p-1)),其差不是p的倍数(所以不会有相同余数),且任一个k*a亦不为p的倍数(所以余数不为0)。因此
即
在这里W=1·2·3·...·(p-1),且(W, p) = 1,因此将整个公式除以W即得到:
Miller-Rabin素数测试的介绍文档
c++实现
#include <algorithm>
#include <iostream>
#include <cmath>
using namespace std;
typedef long long ll;
ll mod_mult(ll a,ll b,ll mod) //(a*b)%mod
{
ll res=0;
a=a%mod;
b=b%mod;
while(b)
{
if(b&1) res=(a+res)%mod;
a=a*2%mod;
b=b>>1;
}
return res;
}
ll mod_pow(ll a,ll b,ll mod) //(a^b)%mod
{
ll res=1;
while(b)
{
if(b&1) res=mod_mult(res,a,mod);
a=mod_mult(a,a,mod);
b=b>>1;
}
return res;
}
bool miller_rabin(int n)
{
if(n==2) return true;
if(n<2) return false;
if(!(n&1)) return false;
ll d=n-1,s=0;
//n-1=d*2^s
// n是素数的话,一定满足下面条件
// (i) a^d ≡ 1 (mod n)
// (ii) a^d, a^2d,..., a^(2^(s-1)*d) 中的某一个对n求模为-1
//
// 所以、当不满足(i)(ii)中的任何一个的时候,就有3/4的概率是合成数
//
while(d%2==0)
{
s++;
d>>=1;
}
for(int i=0;i<20;i++)
{
ll a=rand()%(n-1)+1;
ll x=mod_pow(a,d,n);
if(x==1) continue;
bool flag=false;
for(int j=0;j<s;j++)
{
if(x==n-1)
{
flag=true;
continue;
}
x=mod_mult(x,x,n);
}
if(flag==false) return false;
}
return true;
}