HDU1211 RSA【公匙密码】
原创
©著作权归作者所有:来自51CTO博客作者ITCharge的原创作品,请联系作者获取转载授权,否则将追究法律责任
题目链接:
http://acm.hdu.edu.cn/showproblem.php?pid=1211
题目大意:
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 = D(c) = c^d mod n,解出明文。
AC代码:
#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cstring>
#define LL __int64
using namespace std;
void ExGCD(LL a,LL b,LL &d,LL &x,LL &y)
{
if(b == 0)
{
x = 1;
y = 0;
d = a;
}
else
{
ExGCD(b,a%b,d,y,x);
y -= x*(a/b);
}
}
LL MultiPower(LL a,LL b,LL mo)
{
int res = 1;
while(b > 0)
{
if(b&1)
res = res * a % mo;
a = a*a % mo;
b >>= 1;
}
return res;
}
int main()
{
LL p,q,e,l,d;
while(cin >> p >> q >> e >> l)
{
LL n = p*q;
p = (p-1)*(q-1);
LL x0,y0;
ExGCD(e,p,d,x0,y0);
x0 = (x0%p + p) % p;
for(LL i = 0; i < l; ++i)
{
cin >> d;
LL m = MultiPower(d,x0,n);
printf("%c",m%128);
}
printf("\n");
}
return 0;
}