首页 > 技术文章 > 蓝桥杯2019-省赛-C/C++-A组E题

memocean 2020-02-12 20:55 原文

题目

RSA 解密

【问题描述】

RSA 是一种经典的加密算法。它的基本加密过程如下。

首先生成两个质数 p, q,令 n = p · q,设 d 与 (p − 1) · (q − 1) 互质,则可 找到 e 使得 d · e 除 (p − 1) · (q − 1) 的余数为 1。

n, d, e 组成了私钥,n, d 组成了公钥。

当使用公钥加密一个整数 X 时(小于 n),计算 C = Xd mod n,则 C 是加 密后的密文。

当收到密文 C 时,可使用私钥解开,计算公式为 X = Ce mod n。 例如,当 p = 5, q = 11, d = 3 时,n = 55, e = 27。

若加密数字 24,得 243 mod 55 = 19。 解密数字 19,得 1927 mod 55 = 24。

现在你知道公钥中 n = 1001733993063167141, d = 212353,同时你截获了 别人发送的密文 C = 20190324,请问,原文是多少?

【答案提交】

这是一道结果填空的题,你只需要算出结果后提交即可。本题的结果为一 个整数,在提交答案时只填写这个整数,填写多余的内容将无法得分。

答案

579706994112328949

代码

 1 #include<iostream>
 2 #include<cmath>
 3 #define ll long long
 4 using namespace std;
 5 ll n,d,p,q,e,k;
 6 ll C,X;
 7 ll get_prime(ll num){//num为符合条件的质数d 
 8     for(ll i=2;i<num;i++){
 9         if(num%i==0){//找到能整除的质数! 
10             return i;
11         } 
12     }
13 } 
14 ll phi(ll kk){
15     ll ans=kk;
16     ll end=sqrt(kk+0.5);
17     for(ll i=2;i<=end;i++){
18         if(kk%i==0){
19             ans=ans/i*(i-1);
20             while(kk%i==0) kk/=i;
21         }
22     }
23     if(kk>1)  ans=ans/kk*(kk-1);
24     return ans;
25 }
26 ll fast_mul(ll a,ll b,ll mod){//快速乘,将乘法变成尽可能少加的加法,
27                               //比如,2*5=2+2+2+2+2=((2+2)+(2+2))+(2) 1次乘法->4次加法->3次加法 
28     ll ans=0;
29     a%=mod;
30     b%=mod;
31     while(b>0){
32         if(b&1){
33             ans=(ans+a)%mod;
34         }
35         b>>=1;
36         a=(a+a)%mod;
37     } 
38     return ans;
39     
40 }
41 ll fast_pow(ll a,ll b,ll mod){//快速幂,比挨着一个个乘快,可以减少乘法次数,比如算,a^5=((a^2)*(a^2))*a; 
42     ll mul=1;
43     mul%=mod;
44     while(b>0){
45         if(b&1){
46             mul=fast_mul(mul,a,mod);//二进制表示的b的末尾数为1,就可以相乘 
47         }
48         b>>=1;//二进制表示右移,实际上就是把末尾二进制位置去掉 
49         a=fast_mul(a,a,mod);//计算每一个二次项位置处的值也就是a^(2^i),i∈Z&&i∈[0,len),len为b的二进制表示的位数,
50                             //比如,b是5,那么对应二进制表示就是101,len=3 
51     }
52     return mul; 
53 }
54 int main(){
55     /*
56     n=55;
57     d=3;
58     C=19; 
59     */
60     n=1001733993063167141;
61     d=212353;
62     C=20190324;
63     p=get_prime(n);
64     q=n/p;
65     k=(q-1)*(p-1);
66     ll index=phi(k);
67     //cout<<"p,q,k,index:"<<p<<","<<q<<","<<k<<" "<<index<<endl; 
68     e=fast_pow(d,index-1,k); 
69     //cout<<"e:"<<e<<endl;
70     X=fast_pow(C,e,n); 
71     cout<<"X:"<<X<<endl;
72     
73 }

 

推荐阅读