1. 程式人生 > >HDU1211 密文解鎖 【擴展歐幾裏得】

HDU1211 密文解鎖 【擴展歐幾裏得】

鏈接 long 字母 pro bsp 一個 tar pan 解鎖

<題目鏈接>

<轉載於 >>> >

題目大意:

RSA是個很強大的加密數據的工具,對RSA系統的描述如下:

選擇兩個大素數p、q,計算n = p * q,F(n) = (p-1)*(q-1),選擇一個整數e,使得gcd(e,F(n)) = 1,

e是公匙,計算d使得d * e mod F(n) = 1 mod F(n),d是私匙。加密數據的方法為

C = E(m) = m^e mod n

解密數據的方法為

M = D(c) = c^d mod n

其中,c是密文中字母的ASCII的值;m是明文中字母的ASCII的值。

現在問題來了,給你p、q、e和一些密文,請把密文翻譯成明文。

解題分析:

根據p和q,計算出n = p * q,F(n) = (p-1)*(q-1),用擴展歐幾裏得方法求出e關於F(n)的逆元d,根據

公式 M= c^d mod n,解出明文。

#include <cstdio>

#define ll long long 

ll exgcd(ll a, ll b, ll &x, ll &y)
{
    if (!b)
    {
        x = 1; y = 0;
        return a;
    }
    ll R = exgcd(b, a%b, y, x);
    y -= a / b * x;
    
return R; } ll pow(ll a, ll b,ll mod) { ll ans = 1; while (b) { if (b & 1) { ans = (ans*a) % mod; } b >>= 1; a = (a*a) % mod; } return ans; } int main() { ll q, p, e, l; while (scanf("%lld %lld %lld %lld
", &p, &q, &e, &l) != EOF) { ll n = q * p; ll fn = (q-1)*(p-1); ll d, y; ll gcd=exgcd(e, fn, d, y); d = (d%fn + fn) % fn; //用擴展歐幾裏得方法求出e關於F(n)的逆元d for (ll i = 0; i < l; i++) { ll cal; scanf("%lld", &cal); ll ans = pow(cal, d,n); printf("%c", ans%128); //註意,這裏是 %128 } printf("\n"); } return 0; }

2018-08-12

HDU1211 密文解鎖 【擴展歐幾裏得】