HDU1211 密文解锁 【扩展欧几里得】【逆元】
<题目链接>
<转载于 >>> >
题目大意:
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
作者:is_ok
出处:http://www.cnblogs.com/00isok/
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。
【推荐】还在用 ECharts 开发大屏?试试这款永久免费的开源 BI 工具!
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步