求n的本原根
#include<iostream>
#include<algorithm>
using namespace std;
//判断两个数是否互素
bool IsPrime(int a,int b){
if(__gcd(a,b)==1){
return true;
}else{
return false;
}
}
//得到欧拉函数的值和取值集合
void Euler(int n,int *s,int &sum)
{
for(int i=1;i<n;i++)
{
if(IsPrime(i,n)==1)
{
s[sum]=i;
sum++;
}
}
}
//快速幂取余实现(x^y%n)
int power(long long a,long long b,long long p){
long long res=1;
while(b){
if(b&1)res=res*a%p;
b=b>>1;
a=a*a%p;
}
return res;
}
//根据互素集合利用遍历的方法求本原根
void root(int n,int sum,int s[])
{
int flag[100],k;
for(int i=0;i<sum;i++)
{
k=0;
for(int j=1;j<sum+1;j++)
{
//这里要利用快速幂取余,否则数值太大会溢出
flag[j-1]=power(s[i],j,n);
}
sort(flag,flag+sum);
for(int j=0;j<sum;j++)
{
if(flag[j]!=s[j])
k=1;
}
if(k==0)
cout<<s[i]<<" ";
}
}
int main()
{
int n,sum=0;
int s[100]; //用来存储比n小且与n互素的正整数
cout<<"请输入你想要求本原根的数:";
cin>>n;//97
Euler(n,s,sum);//97
cout<<endl;
cout<<n<<"的所有本原根为:";
root(n,sum,s);
cout<<endl<<endl;
return 0;
}
Diffie-Hellman密钥交换
#include<iostream>
#include<cstring>
#include<algorithm>
using namespace std;
typedef long long LL;
//判断两个数是否互素
bool Isprime(int a,int b){
if(__gcd(a,b)==1){
return true;
}else{
return false;
}
}
//快速幂取余
int fastpower(LL a,LL b,LL p){
LL res=1;
while(b){
if(b&1)res=res*a%p;
b=b>>1;
a=a*a%p;
}
return res;
}
int main(){
//97的所有本原根为:5 7 10 13 14 15 17 21 23 26 29 37 38 39 40 41 56 57 58 59 60 68 71 74 76 80 82 83 84 87 90 92
LL p=97,a=5;//p是大素数 a是p的本原根
LL Xa=36,Xb=58;//Xa 和 Xb为随机保密整数
LL Ya=fastpower(a,Xa,p),Yb=fastpower(a,Xb,p);//Ya=(a^Xa)%p Yb=(a^Xb)%p
LL Ka=fastpower(Yb,Xa,p),Kb=fastpower(Ya,Xb,p);//Ka=(Yb^Xa)%p Kb=(Ya^Xb)%p
cout<<Ka<<" "<<Kb;
}