密碼破解
阿新 • • 發佈:2017-07-21
質因數 分析 之間 pro 卡卡 font pan ont cnblogs
發布時間: 2017年7月9日 18:17 最後更新: 2017年7月9日 21:04 時間限制: 1000ms 內存限制: 128M
描述
近日來勒索病毒的事件頻繁發生,小Y對它的加密原理非常感興趣,研究了一番相關知識之後,他就來給你看他的加密程序,並給你一段密文,和你炫耀說就算把程序給你看你也破解不出來。
你掃了一眼代碼發現加密的公式為b=ae%m ,其中e 是質數。
進一步分析發現m=p?q ,p 和q 都為質數,p!=q ,
作為一個計算機高手,你早就對加密算法爛熟於心,一眼就看出這個程序的算法和原理,找到了破解的方法,發現小Y疏忽在與給了你一個不夠大的m 。
你知道解密的公式與加密對稱,為a=bd%m 。
但是你仍然無法心算解出這個d ,因此你需要借助計算機來將密文破解。
輸入
第一行有一個整數T 表示數據組數。(T<=100 )
接著有T 組數據,每組數據兩行。
第一行有四個數e 、p 、q 和n ,其中e 、p 、q 如題所描述,n 表示需要解密的數字序列長度。
第二行是需要解密的數字序列a1..an 。
1 < p ,q ,e <= 108 ,p 、q 、e 為質數且p!=q 。
$0<=a_i<=i<=n$)< br=""> 保證解密的結果即原數列的值小於min(p,q) 並大於等於0
1<=n<=100
保證m 有且僅有兩個不同的質因數p 和q ,並且一定存在一個題中描述的參數d 使得解密公式能夠無損解密出所有0 ~min(p,q)?1 範圍之間的數字。</M$。($1<=I<=N$)<>
輸出
對於每組數據輸出一行,表示解密後的數字序列,數字之間以空格隔開。
樣例輸入1 復制
1 5 19 29 3 335 440 514
樣例輸出1
65 67 77
這題是RSA加密解密算法,比賽的時候自信寫了,感覺一定過,結果錯了。。。。Orz還一直卡卡交不上去。(註意大整數溢出就好了)
涉及的內容大概就是計算逆元和快速冪,需要註意的是LL乘也會溢出,所以要處理乘。
#include <iostream> #include <stdio.h> using namespace std; typedef long long LL; LL e,p,q,n; int T; void extra_gcd(LL a, LL b, LL &x, LL &y, LL &d) {if(b == 0) { d = a; x = 1; y = 0; } else { extra_gcd(b, a%b, y, x, d); y -= (a/b) * x; } } LL multi_mod(LL a, LL n, LL mod) { LL ans = 0; while(n) { if(n & 1) { ans += a; if(ans > mod) ans -= mod; } n >>= 1; a <<= 1; if(a > mod) a-= mod; } return ans; } LL quick_mod(LL a,LL n,LL mod) { LL ans = 1; while(n) { if(n & 1) ans = multi_mod(ans, a, mod); a = multi_mod(a, a, mod); n >>= 1; } return ans; } int main() { scanf("%d", &T); while(T--) { scanf("%lld%lld%lld%lld",&e,&p,&q,&n); LL m=(p-1)*(q-1); LL y = p*q; LL d, o, l; extra_gcd(e, m, d, o, l); d = ((d%m)+m)%m; for(LL i = 0; i < n; i++) { LL tmp; scanf("%lld", &tmp); tmp %= y; if(i) printf(" "); printf("%lld",quick_mod(tmp,d,y)); } printf("\n"); } return 0; }
密碼破解