题目描述
ElGamal加密体制的公私密钥生成过程如下:
1.加密过程
2.解密过程
输入
加密:
第一行输入0,表示加密操作
第二行输入素数p
第三行输入生成元g
第四行输入私钥
第五行输入明文(明文中的字母按照英文字母表a=00,b=01,…,z=25编码)
第六行输入对应的随机数
解密:
第一行输入1,表示解密操作
第一行输入素数p
第二行输入私钥x
第三行输入密文
输出
加密:
第一行输出公钥中的y
第二行输出密文
解密:
输出明文
输入样例1
0
13171
2
23
bupt
31 16
输出样例1
11852
(4782,8218) (12852,4511)
输入样例2
1
13171
23
(4782,8218) (12852,4511)
输出样例2
bupt
提示
数据格式为十进制
代码:
#include<iostream>
#include <string>
#include <sstream>
#include <vector>
using namespace std;
// 计算幂次方 a^b mod p
int powerMod(int a, int b, int p) {
int res = 1;
a %= p;
while (b > 0) {
if (b & 1)
res = (res * a) % p;
b >>= 1;
a = (a * a) % p;
}
return res;
}
// 将字符串形式的整数转化为整数
int strToInt(string s) {
int res = 0;
for (int i = 0; i < s.size(); ++i) {
res = res * 10 + (int)s[i] - '0';
}
return res;
}
void encrypt()
{
int p, g, x, r1, r2;
string str;
cin >> p >> g >> x >> str >> r1 >> r2;
int y; //公钥y
y = powerMod(g, x, p);
cout << y << endl;
int len = str.length();
int m1=0, m2=0;
for (int i = 0; i < str.length()/2; i++) {
int c = str[i] - 'a';
m1 = m1 * 100 + c;
}
for (int i = str.length() / 2; i < str.length(); i++) {
int c = str[i] - 'a';
m2 = m2 * 100 + c;
}
int c1, c11, c2, c22;
c1 = powerMod(g, r1, p);
c11 = (powerMod(y, r1, p) * m1) % p;
c2 = powerMod(g, r2, p);
c22 = (powerMod(y, r2, p)*m2) % p;
cout << "(" << c1 << "," << c11 << ") " << "(" << c2 << "," << c22 << ")" << endl;
}
void decrypt()
{
int p, x, c1, c11, c2, c22;
string ciphertext;
string ans, t;
cin >> p >> x;
cin.ignore();
getline(cin, ciphertext);
stringstream ss(ciphertext);
string cipherPairStr;
while (getline(ss, cipherPairStr, ' ')) {
t = "";
int pos = cipherPairStr.find(',');
int a = strToInt(cipherPairStr.substr(1, pos - 1));
int b = strToInt(cipherPairStr.substr(pos + 1, cipherPairStr.size() - pos - 2));
int m= (powerMod(a, p - 1 - x, p)*b) % p;
while (m > 0) {
int c = m % 100;
char ch = 'a' + c;
t = ch + t;
m /= 100;
}
ans += t;
}
cout << ans << endl;
}
int main()
{
int type;
cin >> type;
if (type == 0)
{
encrypt();//加密
}
else if (type == 1)
{
decrypt();//解密
}
}