int64范围Miller-Rabin素数测试

费马小定律介绍(基础)

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素数测试的介绍文档

Miller-Rabin素数测试

c++实现

#include 
#include 
#include 
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

 

你可能感兴趣的:(int64范围Miller-Rabin素数测试)