记一次使用快速幂与Miller-Rabin的大素数生成算法
大家都知道RSA的加密的安全性就是能够找到一个合适的大素数,而现在判断大素数的办法有许多,比如Fermat素性测试或者Miller-Rabin素性测试,而这里我用了Miller-Rabin素性测试的算法,具体的理论我写到下面。
算法的理论基础:
- Fermat定理:若n是奇素数,a是任意正整数(1≤ a≤ n−1),则 a^(n-1) ≡ 1 mod n。
2. 如果n是一个奇素数,将n−1表示成2^s*r的形式,r是奇数,a与n是互素的任何随机整数,那么a^r ≡ 1 mod n或者对某个j (0 ≤ j≤ s−1, j∈Z) 等式a^(2jr) ≡ −1 mod n 成立。
实验需要根据这个算法的理论来实现对素数的判定功能,而我将上述理论用C++的 形式写了出来,然后在一些细节的算法上少做润色,成功实现了对素数的生成和判定。
一、实验代码:
#include<iostream>
#include<cmath>
#include<ctime>
#include<cstdlib>
using namespace std;
typedef unsigned long long ll;
long long q_mul( long long a, long long b, long long mod )
{
long long ans = 0;
while(b)
{
if(b & 1)
{
b--;
ans =(ans+ a)%mod;
}
b /= 2;
a = (a + a) % mod;
}
return ans;
}
long long q_pow( long long a, long long b, long long mod )
{
long long ans = 1;
while(b)
{
if(b & 1)
{
ans = q_mul( ans, a, mod );
}
b /= 2;
a = q_mul( a, a, mod );
}
return ans;
}
//long long q_pow(ll a,ll b,ll mod){
// ll base=a;
// ll ans = 1;
// while(b!=0){
// if(b&1) ans = (ans*base)%mod;
// base = (base*base)%mod;
// b>>=1;
// }
// return ans;
//}
int Miller_Rabin(ll n) {
if(n<2) return 0;
if(n==2) return 1;
ll k=0,q=n-1;
while(q%2==0){
q=q/2;
k++;
}
ll a = rand(); //要保证a在(1,n-1)之间,开区间
a=(a%(n-2))+2;
ll result1 = q_pow(a,q,n);
if(result1 == 1||result1 == n-1){
return 1;
}
while(k--){
result1 = q_mul(result1,2,n);
if(result1 == n-1) return 1;
}
return 0;
}
bool True_Miller_Rabin(ll n){
int times = 10;
while(times){
times--;
if(Miller_Rabin(n)==0) return false;
}
return true;
}
int main()
{
srand((unsigned)time(NULL));
ll num;
// while(1){
// cin>>num;
// if(Miller_Rabin(num)==1)
// cout<<"为素数"<<endl;
// else{
// cout<<"是合数"<<endl;
// }
// }
for(ll i=1000000;i<=1005000;i++){
int a =0;
if(True_Miller_Rabin(i)){
cout<< i<<"是素数"<<endl;
}
}
return 0;
}
二、实验结果(自行测试)
这是对1000000000000000000到1000000000000005000里所有素数判定的结果
这是对输入素数的判读
以上结果说明,该程序完全能够胜任在long long类型范围下的素数判定任务。
三、实验总结
本次实验采用了Miller-Rabin算法,而在理解算法的基础上我们要灵活运用。在算法中我最开始用到了C++函数里面的pow函数,然而这个函数导致我素数输出不完整,经过很久的调试,我发现是C++自带库里面的数据类型与long long类型有出入,所以我放弃了使用自带的函数库。之后,我选择了快速幂算法。这个算法比pow函数效果更好,能够对大数进行快速的幂计算。然而在快速幂计算的过程中设计到两个数相乘,当两个Long 类型的数据相乘时会溢出从而导致计算的大素数长度有限。于是我有考虑将幂计算里面的乘法分成若干个加法去进行运算,于是我采用了快速乘与快速幂想结合的方式,也就是我上述代码中绿色的部分(蓝色部分为单纯快速幂),由此我讲幂运算的速度有提升了一个档次,在此基础上也增大了计算素数的范围。
——————Made By Pinging、、、、、hhh Welcome to CUMT。。。
记一次使用快速幂与Miller-Rabin的大素数生成算法的更多相关文章
- TZOJ 5291 游戏之合成(快速幂快速乘)
描述 zzx和city在玩一款小游戏的时候,游戏中有一个宝石合成的功能,需要m个宝石才可以合成下一级的宝石(例如需要m个1级宝石才能合成2级宝石). 这时候zzx问city说“我要合成A级宝石需要多少 ...
- 二分求幂/快速幂取模运算——root(N,k)
二分求幂 int getMi(int a,int b) { ; ) { //当二进制位k位为1时,需要累乘a的2^k次方,然后用ans保存 == ) { ans *= a; } a *= a; b / ...
- 递归实现快速幂(C++版)
快速幂是什么? 顾名思义,快速幂就是快速算底数的n次幂.其时间复杂度为 O(log₂N), 与朴素的O(N)相比效率有了极大的提高. 就以a的b次方来介绍: 把b转换成二进制数,该二进制数第i位的权为 ...
- 洛谷P3758/BZOJ4887 [TJOI2017] 可乐 [矩阵快速幂]
洛谷传送门,BZOJ传送门 可乐 Time Limit: 10 Sec Memory Limit: 64 MBSubmit: 299 Solved: 207 Description 加里敦星球的人 ...
- $Miller Rabin$总结
\(Miller Rabin\)总结: 这是一个很高效的判断质数的方法,可以在用\(O(logn)\) 的复杂度快速判断一个数是否是质数.它运用了费马小定理和二次探测定理这两个筛质数效率极高的方法. ...
- 关于素数:求不超过n的素数,素数的判定(Miller Rabin 测试)
关于素数的基本介绍请参考百度百科here和维基百科here的介绍 首先介绍几条关于素数的基本定理: 定理1:如果n不是素数,则n至少有一个( 1, sqrt(n) ]范围内的的因子 定理2:如果n不是 ...
- 【66测试20161115】【树】【DP_LIS】【SPFA】【同余最短路】【递推】【矩阵快速幂】
还有3天,今天考试又崩了.状态还没有调整过来... 第一题:小L的二叉树 勤奋又善于思考的小L接触了信息学竞赛,开始的学习十分顺利.但是,小L对数据结构的掌握实在十分渣渣.所以,小L当时卡在了二叉树. ...
- hdu 1568 Fibonacci 快速幂
Fibonacci Time Limit: 1000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Proble ...
- BZOJ_[HNOI2008]_Cards_(置换+Burnside引理+乘法逆元+费马小定理+快速幂)
描述 http://www.lydsy.com/JudgeOnline/problem.php?id=1004 共n个卡片,染成r,b,g三种颜色,每种颜色的个数有规定.给出一些置换,可以由置换得到的 ...
随机推荐
- MySQL(二)之服务管理与初始化文件修改和连接MySQL
上一篇给大家介绍了怎么在linux和windows中安装mysql,本来是可以放在首页的,但是博客园说“安装配置类文件”不让放在首页.接下来给大家介绍一下在linux和windows下MySQL的一下 ...
- Cython的用法以及填坑姿势
因为项目需要,需要优化已有的Python代码.目前Python代码的执行过程是将Python代码转变成一行行指令,然后解释器解释指令的执行,调用到C代码层.如果去掉指令解释这个阶段,直接进入C代码层, ...
- [js高手之路]深入浅出webpack教程系列3-配置文件webpack.config.js详解(下)
本文继续接着上文,继续写下webpack.config.js的其他配置用法. 一.把两个文件打包成一个,entry怎么配置? 在上文中的webpack.dev.config.js中,用数组配置entr ...
- springboot 入门二- 读取配置信息一
在上篇入门中简单介绍下springboot启动使用了大量的默认配置,在实际开发过程中,经常需要启动多个服务,那端口如何手动修改呢? 此篇就是简单介绍相关的配置文件信息. Spring Boot允许外部 ...
- Java 优先队列
Java PriorityQueue 优先队列是一种重要的数据结构,其利用的是小/大顶堆来实现的. Java中提供了PriorityQueue,PriorityQueue是基于小顶堆实现的无界优先队列 ...
- C++IO类&文件输入输出
C++IO类&文件输入输出 istream(输入流)类型,提供输入操作. ostream(输出流)类型,提供输出操作. cin,一个istream对象,从标准输入读取数据. cout,一个os ...
- OpenSSL中的大数接口与基于其的自用RSA加密接口设计
本文记录了初次接触OpenSSL中的大数模块,重温了RSA加密流程,使用OpenSSL的接口包装成自用RSA加密接口,并且利用自己的接口演示了Alice与Bob通过RSA加密进行通讯的一个示例. 概览 ...
- 个人作业3——个人总结(Alpha阶段)
个人总结 Alpha阶段总结: 起初关于手机app的开发真的一无所知,选了一条较远的路走(使用 Android Studio 来开发 Android 应用更加方便,而我们选用 Eclipse 开发 A ...
- 【2017集美大学1412软工实践_助教博客】团队作业5——测试与发布(Alpha版本)
第五次团队作业成绩公布 题目 团队作业5: http://www.cnblogs.com/happyzm/p/6788792.html 团队成绩 成绩公示如下: 检查项 测试报告 Alpha版本发布说 ...
- 结队编程-基于gui的四则运算生成器
成员:卢少锐 201421123027.刘存201421033023 coding.net地址 1.需求分析:除了实现四则运算的功能外,还添加了计时器功能和语言选择功能 2.程序设计:这次作业是基于上 ...