HDU1211 密文解鎖 【擴展歐幾裏得】
阿新 • • 發佈:2018-08-12
鏈接 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 密文解鎖 【擴展歐幾裏得】