HDU1211 RSA【公匙密码】

题目链接:

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;
}


你可能感兴趣的:(HDU1211 RSA【公匙密码】)