Miller Rabin算法
来源:互联网 发布:c语言中short什么意思 编辑:程序博客网 时间:2024/06/07 20:19
首先 介绍一下费马小定理
定义:假如p是质数,且gcd(a,p)=1,那么 a^(p-1)≡1(mod p)
当p为素数 a^(p-1) = 1 (mod p) 一定成立
当a^(p-1) = 1 (mod p)成立时 p很可能为素数
所以可以用作素数测试(但不一定准确)
证明费马小定理前 先证明:a,2a,3a,....,(p-1)a分别除以p 余数将得到1,2,3....,(p-1)例如a=3 p=43,6,9 分别除以 4 得:3 2 1反证法证明:假设存在正整数n,m 满足0<n<m<p 且 na%p == ma%pna%p = ma%p --> ma%p - na%p = 0 --> a(m-n)%p = 0因为m-n>=1 且 (m-n)<p 且 a<p所以a(m-n)不可能含有因子p 与 a(m-n)%p = 0 矛盾 -->假设不成立所以:a%p * 2a%p * .... * (p-1)a%p = (p-1)! (p-1)!*a^(p-1) = (p-1)! (mod p)消去2边的(p-1)!得: a^(p-1) = 1 (mod p)
后来 Miller和Rabin根据以下定理 对基于费马小定理的素数测试进行改进 使得准确率大大提高
对小于素数 p 的正整数 x 有: 当 x^2 = 1 (mod p) 时 x = 1或p - 1
证明:因为:x^2-1 = (x + 1)*(x - 1) --> (x + 1)*(x - 1) % p = 0因为x < p p为素数所以只有当x = 1时 : 2*0%p = 0或 当 x = p - 1时 p * (p - 2) % p = 0
Miller-Rabin:
如果 a^(p-1) = 1 (mod p)因为大于2的素数p都是奇数 p-1都是偶数所以 p - 1可以表示为 d*2^r r为(p-1)中2的因子个数--> a^(d*2^r) = 1 (mod p)令x = a^(d*2^(r-1))则 x^2 = 1 (mod p)x%p = 1或p-1显然 对x[i] = a^(d*2^(r-i)) i<=r都成立Ps: x[i] = x[i+1]^2---------先检验a^(p-1) = 1 (mod p)是否成立①成立:令x[i] = a^(d*2^(r-i)) i<=r如果x[i]%p 不等于1或p-1 p一定不是素数如果x[i]%p = 1 即:x[i+1]^2 = 1(mod p) 继续检查 x[i+1]%p如果x[i]%p = p-1或检查完所有x[i] 则p很可能为素数②不成立:p一定不是素数
例题:
51NOD 1186 质数检测 V2
nefu 120 梅森素数
质数检测V2
//偷懒用javaimport java.io.BufferedInputStream;import java.math.BigInteger;import java.util.Random;import java.util.Scanner;public class Main { final static BigInteger two = BigInteger.valueOf(2); static boolean witness(BigInteger a,BigInteger n){//合数返回true 素数false BigInteger m = n.subtract(BigInteger.ONE);//m=n-1 int j=0; while(m.mod(two).intValue()==0){//n-1 = m*(2^j) ++j; m = m.divide(two); } BigInteger x = a.modPow(m,n);//x=a^m (mod n) if(x.compareTo(BigInteger.ONE)==0||x.compareTo(n.subtract(BigInteger.ONE))==0) return false; while(j-->0){ x = x.multiply(x).mod(n); if(x.compareTo(n.subtract(BigInteger.ONE))==0) return false; } return true; } static boolean Miller_Rabin(BigInteger n){ final int Times = 12;//测试12次 if(n.compareTo(two)==0) return true; if(n.compareTo(two)<=-1||n.mod(two).intValue()==0) return false; Random random = new Random(); BigInteger nSub1 = n.subtract(BigInteger.ONE); for(int i=0;i<Times;++i){ BigInteger a = BigInteger.valueOf(random.nextInt(100) + 1); a = nSub1.min(a); if(witness(a,n)) return false; } return true; } public static void main(String[] args) { Scanner scanner = new Scanner(System.in); BigInteger n = scanner.nextBigInteger(); if(Miller_Rabin(n)){ System.out.println("Yes"); } else{ System.out.println("No"); } }}
梅森素数
#include<iostream>#include<stdlib.h>#include<stdio.h>#include<string>#include<vector>#include<deque>#include<queue>#include<algorithm>#include<set>#include<map>#include<stack>#include<time.h>#include<math.h>#include<list>#include<cstring>#include<fstream>//#include<memory.h>using namespace std;#define ll long long#define ull unsigned long long#define pii pair<int,int>#define INF 1000000007#define pll pair<ll,ll>#define pid pair<int,double>ll multi(ll a,ll b,ll mod){//(a*b)%mod ll ans=0; while(b){ if(b&1){ ans = (ans + a) % mod; } b >>= 1; a = (a << 1) % mod; } return ans;}ll quick_mod(ll a,ll b,ll mod){ ll ans=1; a%=mod; while(b){ if(b&1){ ans = multi(a,ans,mod); } b>>=1; a = multi(a,a,mod); } return ans;}bool witness(ll a,ll n){//noprime ll m = n - 1; int j=0; while(0==(m&1)){//n-1 = m*(2^j) ++j; m>>=1; } ll x = quick_mod(a,m,n);//x=a^m (mod n) if(x==1||x==n-1) return false; while(j--){ x = x*x%n; if(x == n-1) return false; } return true;}bool Miller_Rabin(ll n){ const int Times = 12; if(n==2) return true; if(n<2||n%2==0) return false; for(int i=0;i<Times;++i){ ll a = rand()%(n-1) + 1; if(witness(a,n)) return false; } return true;}int main(){ //freopen("/home/lu/文档/r.txt","r",stdin); //freopen("/home/lu/文档/w.txt","w",stdout); int T,p; ll x; scanf("%d",&T); while(T--){ scanf("%d",&p); ll n = (ll)1<<p; puts(Miller_Rabin(n-1)?"yes":"no"); } return 0;}
0 0
- bzoj3667 Rabin-Miller算法【Rabin-Miller+pollard_rho】
- Miller-Rabin算法
- miller-rabin,Pollard_rho算法
- Miller-Rabin算法
- 【BZOJ3667】Rabin-Miller算法
- BZOJ3667: Rabin-Miller算法
- bzoj3667: Rabin-Miller算法
- Rabin-Miller算法
- Miller Rabin算法
- 3667: Rabin-Miller算法
- bzoj3667: Rabin-Miller算法
- bzoj3667 Rabin-Miller算法
- Miller-Rabin算法
- 3667: Rabin-Miller算法
- BZOJ3667:Rabin-Miller算法
- 【素数算法】Rabin-Miller算法
- Rabin -Miller算法判定素数
- 判断素数 Miller-Rabin 算法
- Ubuntu16.04 Oracle JDK安装配置
- Javascript 之入门
- 前端开发小技巧——取消a标签点击之后的虚线框
- Java快速查找21位花朵数
- source insight 头文件与源文件切换
- Miller Rabin算法
- 如何判断int数据类型为空
- 结对测试工具——PICT用户手册(中文版)
- C语言中exit 0和exit 1 的区别
- flume学习(七):自定义source
- 【Codeforces 141CQueue】+ 数组构造
- Azkaban安装
- 03、C语言-数组
- 杨小白信箱