大数素性检验

大数素性检验:

  1 #include <iostream>
  2 #include <stdlib.h>
  3 //#include "big.h"
  4
  5 //#pragma comment(lib, "miracl.lib")
  6 using namespace std;
  7
  8 // Montgomery 快速幂模算法(n^p)%m
  9 unsigned __int64 Montgomery(unsigned __int64 n, unsigned __int64 p, unsigned __int64 m)
 10 {
 11     unsigned __int64 r = n % m;
 12     unsigned __int64 k = 1;
 13     while (p > 1)
 14     {
 15         if ((p & 1) != 0)
 16         {
 17             k = (k * r) % m;
 18         }
 19         r = (r * r) % m;
 20         p >>= 1;
 21     }
 22     return (r * k) % m;
 23 }
 24
 25 // 返回true:n是合数, 返回false:n是素数
 26 bool R_M_Help(unsigned __int64 a, unsigned __int64 k, unsigned __int64 q, unsigned __int64 n)
 27 {
 28     if (1 != Montgomery(a, q, n))
 29     {
 30         int e = 1;
 31         for (int i = 0; i < k; ++i)
 32         {
 33             if (n - 1 == Montgomery(a, q * e, n))
 34                 return false;
 35             e <<= 1;
 36         }
 37         return true;
 38     }
 39     return false;
 40 }
 41
 42 //拉宾-米勒测试 返回true:n是合数, 返回false:n是素数
 43 bool R_M(unsigned __int64 n)
 44 {
 45     if (n < 2)
 46         throw 0;
 47     if (n == 2 || n == 3)
 48     {
 49         return false;
 50     }
 51     if ((n & 1) == 0)
 52         return true;
 53
 54     // 找到k和q, n = 2^k * q + 1;
 55     unsigned __int64 k = 0, q = n - 1;
 56     while (0 == (q & 1))
 57     {
 58         q >>= 1;
 59         k++;
 60     }
 61     /*if n < 1,373,653, it is enough to test a = 2 and 3.
 62     if n < 9,080,191, it is enough to test a = 31 and 73.
 63     if n < 4,759,123,141, it is enough to test a = 2, 7, and 61.
 64     if n < 2,152,302,898,747, it is enough to test a = 2, 3, 5, 7, and 11.*/
 65     if (n < 1373653)
 66     {
 67         if (R_M_Help(2, k, q, n) || R_M_Help(3, k, q, n))
 68             return true;
 69     }
 70     else if (n < 9080191)
 71     {
 72         if (R_M_Help(31, k, q, n) || R_M_Help(73, k, q, n))
 73             return true;
 74     }
 75     else if (n < 4759123141)
 76     {
 77         if (R_M_Help(2, k, q, n)
 78             || R_M_Help(3, k, q, n)
 79             || R_M_Help(5, k, q, n)
 80             || R_M_Help(11, k, q, n))
 81             return true;
 82     }
 83     else if (n < 2152302898747)
 84     {
 85         if (R_M_Help(2, k, q, n)
 86             || R_M_Help(3, k, q, n)
 87             || R_M_Help(5, k, q, n)
 88             || R_M_Help(7, k, q, n)
 89             || R_M_Help(11, k, q, n))
 90             return true;
 91     }
 92     else
 93     {
 94         if (R_M_Help(2, k, q, n)
 95             || R_M_Help(3, k, q, n)
 96             || R_M_Help(5, k, q, n)
 97             || R_M_Help(7, k, q, n)
 98             || R_M_Help(11, k, q, n)
 99             || R_M_Help(31, k, q, n)
100             || R_M_Help(61, k, q, n)
101             || R_M_Help(73, k, q, n))
102             return true;
103     }
104     return false;
105 }
106
107 int main()
108 {
109     ////初始化一个500位10进制的大数系统
110     //Miracl precision(500, 10);
111     //char a[512];
112     //memset(a, 0, 512);
113
114     //big p = mirvar(0); //大素数p
115     //expb2(100, p);
116
117     //while (1)
118     //{
119     //    // nxprime(pd,x)找到一个x大于pd的素数,返回值为BOOL
120     //    nxprime(p, p);
121
122     //    // 将一个大数根据其进制转换成一个字符串
123     //    cotstr(p, a);
124     //    if (isprime(p))
125     //        cout << "p is a prime!" << "\n" << a << "\n";
126     //    getchar();
127
128     //}
129
130     long long num;
131     while (1)
132     {
133         scanf_s("%lld",&num);
134         if (!R_M(num))
135         {
136             cout << "Is prime num." << endl;
137         }
138         else
139         {
140             cout << "No." << endl;
141         }
142
143     }
144
145     return 0;
146 }
时间: 2024-11-08 19:24:05

大数素性检验的相关文章

【算法】米勒-拉宾素性检验

Prime or Not: Given the number, you are to answer the question: "Is it prime?" Input: t – the number of test cases, then t test cases follows. [t ≤ 500] Each line contains one integer: N [2 ≤ N ≤ 263-1] Output: For each test case output string &

米勒-拉宾素性测试学习

之前一直对于这个神奇的素性判定方法感到痴迷而又没有时间去了解.借着学习<信息安全数学基础>将素性这一判定方法学习一遍. 首先证明一下费马小定理. 若p为素数,且gcd(a, p)=1, 则有 a^(p-1) = 1 (mod p) 基于以下定理 若(a, p)=1,{x| (x, p)=1}为模p下的一个完全剩余系,则{ax| (x, p)=1}也为模p下的一个完全剩余系. 又{0, 1, 2, ... p-1}为模p下一个剩余系   因此有, {a*0, a*1, a*2, ... a*(p

Miller_Rabin大质数检验

质数检验有不少算法,一般使用的质数检验复杂度是\(O(\sqrt{n})\): 又如线性筛可以在\(O(n)\)的时间内求出所有1~n的质数 但是,当n非常大,连\(O(\sqrt{n})\)的复杂度也难以接受时,上述算法便不能满足要求 这篇blog记录了一些关于Miller_Rabin算法的内容 大家都知道的著名的费马小定理: \[a^{p-1}\equiv1\pmod p\] 其中\(a,p\)互质 我们猜想,任意选取\(a\),如果一个数\(p\)满足以上式子,那么它就很有可能是一个质数

质因数分解的rho以及miller-rabin

一.前言 质因数分解,是一个在算法竞赛里老生常谈的经典问题.我们在解决许多问题的时候需要用到质因数分解来辅助运算,而且质因数分解牵扯到许许多多经典高效的算法,例如miller-rabin判断素数算法,rho启发式搜索质因数分解算法等.在此文里,我要介绍的就是miller-rabin算法以及rho启发式搜索分解算法. 二.算术基本定理 首先,我们得知道,任意一个大于1的自然数都可以分解为有限个质数的乘积.这里因子均为质数,且为正整数.我们把这样的分解成为N的标准分解式.关于算数基本定理的应用有许多

大整数运算C++1

//下面的代码勉强算是bignum_beta1版本! //实现了大整数的加减乘除四则运算,以及求两个整数的最大公约数,以及求乘法逆,miller_rabin素性检验,平方_乘法算法 //不足之处,位数还很难扩展至几千位,以及运算速度有一点慢,既然是beta1,说明bug还是挺多的 //程序缺少测试数据来测试,所以有的结果不敢保证其正确性 //由于使用c++复写了很多运算符,加入这个文件之后,大数bignum可以看做是一个如同如同int一样的基本类型 //可以像int一样加减乘除和输入输出 #in

大整数运算C++

//下面的代码勉强算是bignum_beta1版本! //实现了大整数的加减乘除四则运算,以及求两个整数的最大公约数,以及求乘法逆,miller_rabin素性检验,平方_乘法算法 //不足之处,位数还很难扩展至几千位,以及运算速度有一点慢,既然是beta1,说明bug还是挺多的 //程序缺少测试数据来测试,所以有的结果不敢保证其正确性 //由于使用c++复写了很多运算符,加入这个文件之后,大数bignum可以看做是一个如同如同int一样的基本类型 //可以像int一样加减乘除和输入输出 #in

Pollard-rho的质因数分解

思路:见参考文章(原理我是写不粗来了) 代码: 用到了快速幂,米勒罗宾素性检验. 1 #include <iostream> 2 #include <time.h> 3 #include <map> 4 using namespace std; 5 long long an[] = {2,3,5,7,11,13,17,61}; 6 map<long long,int> mp;//存因数和对应出现次数 7 int num = 0; 8 long long Ra

如何判断素数

在OI与密码学等各个方面,我们经常会遇到需要判断素数的情况.这个问题看似简单,实则不然.判素就像是排序,只会快排是不能走遍天下的,想要成为一名神犇,就需要接触更多的算法. 一:什么是素数 素数,也可以叫做质数.如果一个大于1的自然数,除去1和他本身,不能被其他数字整除,那么他就是一个素数.任何一个大于1的自然数,要么是素数,要么是可以写做一堆素数相乘. 二:素数的性质 (1)质数p的约数只有两个:1和p. (2)初等数学基本定理:任一大于1的自然数,要么本身是质数,要么可以分解为几个质数之积,且

数论基础的补充讲解

数论基础的补充讲解 整除的一些性质: (1)能被2整除的数,个位上的数都能被2整除 (2*)能被4整除的数,个位和十位所组成的两位数能被4整除 (3*)能被8整除的数,百位.十位和个位所组成的三位数能被8整除 (4)能被5整除的数,末尾是0或5 (5*)能被25整除的数,十位和个位所组成的两位数能被25整除 (6*)能被125整除的数,百位.十位和个位所组成的三位数能被125整除 (7)能被3整除的数,各个数位上的数字之和能被3整除 (8*)能被9整除的数,各个数位上的数字和能被 9 整除 (9