RSA加密算法的C++实现(仅为理解用)

这篇文章是RSA加密算法的简易版本,密钥支持不了1024位,水平有限,只是拿来作为理解RSA加密的(怕自己以后忘了)

#include<iostream>
#include<cmath>
using namespace std;

int fast_mod(int base,int exp,int mod)//快速幂模运算
{
    
    int ans=1;
    while(exp!=0)
    {
        if(exp&1)
        {
            ans=(ans*base)%mod;
           
        }
        base=(base*base)%mod;
        exp=exp>>1;
    }
   
    return ans; 
}
int gcd(int a,int b)//最大公约数计算
{
    int c=0;
    if(a<b)//默认a为不小于b
    {
        c=a;
        a=b;
        b=c;
    }
    c=a;
    a=b;
    b=c%b;
    if(b==0)
        return a;
    else
        return gcd(a,b);
}
bool test_prime_number(int num)//利用费马定理进行概率素数检验
{
    int k=fast_mod(2,num-1,num)+fast_mod(3,num-1,num)+ fast_mod(5,num-1,num);
    if(k==3)
        return true;
    else
    {
        return false;
    }
    
    }
int count_Euler_value(int v)//计算一个数的欧拉值
{
   
    int re=v;
    for(int i=2;i<v;i++)
    {
        if(v%i==0)
        {
            re/=i;
            re*=i-1;
        }
    }
    return re;
}
int count_private_key(int e, int u)//计算私钥  ex=1(mod u) => ex+uy=1
{
    int count_d(int,int,int);
    if(gcd(e,u)!=1)
    {
        cout<<"ERROR1:公钥和模数的欧拉值不互质"<<endl;
    }
    return count_d(e,u,1);
}
int count_d(int a,int b,int c)//ax+by=c
{
    if(c%(gcd(a,b))!=0)
    {
        cout<<"ERROR2:该一元二次方程无解"<<endl;
        return 0;
    }
    void ext_gcd(int,int,int,int &,int &);
    if(a<b)
    {
        int y=count_d(b,a,c);
        int x=(c-b*y)/a;
        return x;
    }
    int x,y;
    int s=gcd(gcd(a,b),c);
     a/=s;
     b/=s;
     c/=s;
    int k=gcd(a,b);
    ext_gcd(a,b,k,x,y);//结果为k的解x,y
    return x*(c/k);
}
void ext_gcd(int a,int b,int k,int & x,int &y)//扩展欧几里得算法
{
    int c=a/b;//a=b*c+d
    int d=a%b;
    if(d==k)
    {
        x=1;
        y=-1*c;
        return;
    }
    else if(d==0)
    {
        x=0;y=1;
        return;
    }
    
    int x1,y1;
    ext_gcd(b,d,k,x1,y1);
    x=y1;
    y=c*y1*-1+x1;

}
int main()
{
    int p,q,public_key,private_key;
    cout<<"input the first prime number"<<endl;
    while (1)
    {
        /* code */
        cin>>p;
        if(test_prime_number(p))
            break;
        cout<<"It is not a prime number, please input another one"<<endl;
    }
    cout<<"input the second prime number"<<endl;
    while (1)
    {
        /* code */
        cin>>q;
        if(test_prime_number(q))
            break;
        cout<<"It is not a prime number, please input another one"<<endl;
    }
    cout<<"input a number which coprime with the product of the front two prime number "<<endl;
    int pq=p*q;
    while (1)
    {
        cin>>public_key;
        if(gcd(public_key,count_Euler_value(pq))!=1)
        {
            cout<<"the number isn't appropriate"<<endl;
            continue;
        }
        break;
        /* code */
    }
    
    private_key=count_private_key(public_key,count_Euler_value(pq));
    if(private_key<0)
        private_key+=count_Euler_value(pq);
    cout<<"---------------------------------------------------------------------------------------------------"<<endl;
    cout<<"The public key is ("<<p*q<<","<<public_key<<")"<<endl;
    cout<<"The private key is ("<<p*q<<","<<private_key<<")"<<endl;
    cout<<"---------------------------------------------------------------------------------------------------"<<endl;
    cout<<"the string for encoding ";
    string str;
    cin>>str;
    cout<<"the result of encoding"<<endl;
    int asc;

    char ch;
    int list[1000];
    for(int i=0;i<str.length();i++)
    {
        asc=(char)str[i];
       list[i]= fast_mod(asc,public_key,pq);
        cout<<list[i]<<" ";
    }
    cout<<endl;

    cout<<"the result of decoding"<<endl;
    for(int i=0;i<str.length();i++)
    {
        int k=fast_mod(list[i],private_key,pq);
        ch=fast_mod(list[i],private_key,pq);
        cout<<ch<<" ";
    }
    cout<<endl;
    //cout<<fast_mod(100,1000,9)<<endl<<gcd(1234,8)<<endl<<test_prime_number(111)<<endl<<;
    return 0;
}


附:由于使用int类型,所以那两个素数的乘积最好不超过4位数

结果
在这里插入图片描述

  • 0
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值