实验8-有关RSA加解密的题目-C++

实验题目:素性检测
实验原理:
这里介绍了大素数的一些产生方法,包括:
1、Miller-Rabin素性检测;
在这里插入图片描述
2、Solovay-Stassen素性检测;
在这里插入图片描述
3、Fermat素性检测;等等
在这里插入图片描述
实验任务:
1、求100至200之间的素数。
代码如下:

#include<bits/stdc++.h> 
#include<iostream>
using namespace std;

bool isprime(int n){
	
	for(int i=2;i<=sqrt(n);i++){
		if(n%i==0){
			return false;
		}
	}
	return true;
} 
int main(){
	
	cout<<"100-200之间的素数如下"<<endl; 
	for(int i=100;i<=200;i++){
		if(isprime(i)){
			cout<<i<<endl;
		}
	}
	
} 

2、利用Miller Babin素数筛法求出一个不小于1000的素数。

#include<bits/stdc++.h> 
#include<iostream>
using namespace std;

#define random(a,b) (rand()%(b-a+1)+a) //[a,b]直接的随机数 
typedef long long int ll;

//计算 rx*ry mod m 
ll mod_mul(ll rx, ll ry, ll mod){
	return (rx*ry)%mod;
}

// b^t mod m
ll mod_pow(ll b, ll t,ll mod){
	
	//据太大 这样来处理 
	ll number=1; 
	ll num=b;
	for(ll j=0;j<t;j++){
		number=(number*num)%mod;
	 }
	 return number;
	 
}

ll k;
ll s;
ll t; 
bool Miller_Babin(ll n){
	
	//求s,t 
	ll m=n-1;
	s=0;
	while(!(m&1)){
		s++;
		m>>=1;
	}
	
	t=m;
	//cout<<"s,t的值"<<endl; 
	//cout<<s<<" "<<t<<endl;
	
	for(int i=1;i<=k;i++){//循环安全参数k次 
		ll b=random(2,n-2);
		ll r0=mod_pow(b,t,n);
		if(r0==1|| r0==n-1){
			continue;
		}
		
		int flag=1;
		for(int j=1;j<=s-1;j++){
			
			ll r1=mod_mul(r0,r0,n);
			if(r1==n-1){
				flag=0;
				break;
			}else{
				r0=r1;
			}
		}
		if(flag==1){
			return false;
		}
			 	
	}
	return true;	
}

int main(){
	
	srand((unsigned)time(NULL));
	cout<<"请输入安全参数"<<endl;
	cin>>k;
	for(ll i=1001;;i++){
		
		if(i%2==0){//保证输入为奇整数 
			continue;
		}
		if(Miller_Babin(i)){
			cout<<"s,t的值"<<endl; 
			cout<<s<<" "<<t<<endl;
			cout<<endl;
			cout<<i<<endl;
			return 0;
		}
	}  
} 

3、求如下整数对的最大公因数
(55,85) (202,282)

#include<bits/stdc++.h> 
#include<iostream>
using namespace std;
/*
举例:求8251与6105的最大公约数,
8251=6105x1+2164
6105=2146x2+1813,
2164=1813x1+333,
1813=333x5+148,
333=148x2+37,
148=37x4,∴37是148和37的最大公约数,也就是8251和6105的最大公约数。
*/

//辗转相除法求最大公因数 
int Max_Gcd(int a,int b){
	
	if(a<b){
		swap(a,b);
	}
	
	int Z=0,Mod=-1;
	
	int flag=1;
	int result=0;
	while(Mod!=0){//余数不为0则 接着循环 
		Z=a/b;
		Mod=a%b;
		
		if(flag==1 && Mod==0){
			result=b;
			flag=0;
			break;
		}
		
		if(Mod!=0){
			result=Mod;
		}
		
		a=b;
		b=Mod;
		
	}
	return result;
	 
	
}
int main(){
	
	int k;
	cout<<"输入你测试数据的个数"<<endl;
	cin>>k;
	while(k--){
		cout<<"输入数据a和数据b,中间以空格隔开"<<endl; 
		int a,b;
		cin>>a>>b;
		cout<<Max_Gcd(a,b)<<endl;
	} 

}

4、运用广义欧几里得除法求整数s,t,使得sa+tb=(a,b)
(1)1613,3589 (2)2947,3772
分析思路:

在这里插入图片描述

#include<bits/stdc++.h> 
#include<iostream>
using namespace std;
/*
	3589= 2*1613+363,
	1613= 4*363+161,
	363= 2*161+41,
	161=3*41+38,
	41=1*38+3,
	38=12*3+2,
	3=1*2+1,
	2=2*1

	 1=3-2*1
	  =3-(38-12*3)*1
	  =-38+(41-1*38)*13
	  =41*13-(161-3*41)*14
	  =-14*161+(363-2*161)*55
	  =363*55-(1613-4*363)*124
	  =-1613*124+(3589-2*1613)*551
 	  =551*3589-1226*1613
	即s=551,t=-1226.
	
	改变书写格式总结规律:
	3+(-1)*2=1;
	38+(-12)*3=2;
	41+(-1)*38 =3;
	161+(-3)*41=38;
	363+(-2)*161=41;
	1613+(-4)*363=161;
	3589 +(-2)*1613=363; 	
*/
//辗转相除法求最大公因数 
vector<int> q;

int result;//记录最大公约数 
int Max_Gcd(int a,int b){
	
	int count=0;
	if(a<b){
		swap(a,b);
	}
	
	int Z=0,Mod=-1;
	
	
	while(Mod!=0){//余数不为0则 接着循环 
		Z=a/b;
		Mod=a%b;
		q.push_back(Z);//记录q值 
		count++;//记录运算步骤 
		
		if(Mod!=0){
			result=Mod;
			
		}
		a=b;
		b=Mod;
		
	}
	return count;

	
}
int main(){
	
	int k;
	cout<<"输入你测试数据的个数"<<endl;
	cin>>k;
	while(k--){
		cout<<"输入数据a和数据b,中间以空格隔开"<<endl; 
		int a,b;
		cin>>a>>b;
		int count=Max_Gcd(a,b);
		cout<<"最大公约数为:"<<endl;
		cout<<result<<endl;
		
		vector<int> q_;
		for(int i=q.size()-2;i>=0;i--){
			q_.push_back(-q[i]);
		}
		cout<<"调整好之后的q的值如下:"<<endl; 
		for(int i=0;i<q_.size();i++){
			cout<<q_[i]<<" ";
		}
		cout<<endl;
        cout<<"循环次数如下"<<endl; 
		cout<<count-2;
		cout<<endl;
		
		//倒推求解规律如下 
         int a1[1005];
         int b1[1005];
         a1[0]=1;
         b1[0]=q_[0];
        for(int i=1;i<=count-2;i++){
        	a1[i]=b1[i-1];
        	b1[i]=b1[i-1]*q_[i]+a1[i-1];
		}
		cout<<"结果为"<<endl; 
		if(a>b){
			cout<<a1[count-2]<<" "<<b1[count-2]; 
		}else{
			cout<<b1[count-2]<<" "<<a1[count-2];
		}
		q.clear();
		cout<<endl;
	} 
	
	
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值