密碼破解

發佈時間: 2017年7月9日 18:17   最後更新: 2017年7月9日 21:04   時間限制: 1000ms   內存限制: 128M

描述ios

近日來勒索病毒的事件頻繁發生,小Y對它的加密原理很是感興趣,研究了一番相關知識以後,他就來給你看他的加密程序,並給你一段密文,和你炫耀說就算把程序給你看你也破解不出來。算法

你掃了一眼代碼發現加密的公式爲b=ae%m ,其中e 是質數。ui

進一步分析發現m=p∗q ,p 和q 都爲質數,p!=q ,加密

做爲一個計算機高手,你早就對加密算法爛熟於心,一眼就看出這個程序的算法和原理,找到了破解的方法,發現小Y疏忽在與給了你一個不夠大的m 。spa

你知道解密的公式與加密對稱,爲a=bd%m 。code

可是你仍然沒法心算解出這個d ,所以你須要藉助計算機來將密文破解。blog

輸入事件

第一行有一個整數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$)<>內存

輸出get

對於每組數據輸出一行,表示解密後的數字序列,數字之間以空格隔開。

樣例輸入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;
}
相關文章
相關標籤/搜索