原理不再细述, 下面是简单的实现,没有使用比较大的质数, 主要是用C++不想写大数…
支持对中文的加密
#include
using namespace std;
typedef long long LL;
const int MAX_N = 1000;
wifstream wfin;
wofstream wfout;
//locale loc("zh_CN.UTF-8"); //Linux 下需要
//拓展欧几里得 已知a,b 求满足ax + by = gcd(a, b) 的一组解
int exgcd(int a, int b, int &x, int &y)
{
if (b == 0){
x = 1;
y = 0;
return a;
}
int ans = exgcd(b, a % b, x, y);
int tmp = x;
x = y;
y = tmp - a / b * y;
return ans;
}
// 暴力找出200 ~ MAX_N 的所有质数
void get_Prime_Number(int *Prime, int &cnt)
{
cnt = 0;
for (int i = 201;i < MAX_N; i+=2){
bool flag = false;
for (int j = 2;(j * j) <= i; j++){
if (i % j == 0){
flag = true;
break;
}
}
if (!flag) Prime[cnt++] = i;
}
}
//RSA初始化
void RSA_Initialize(int &n, int &e, int &d)
{
int Prime[MAX_N], cnt = 0;
get_Prime_Number(Prime, cnt);
srand((unsigned)time(NULL));
int r1 = rand() % cnt;
int r2 = rand() % cnt;
int p1 = Prime[r1], p2 = Prime[r2]; // 随机取两个质数.
n = p1 * p2; // 计算n
int m = (p1 - 1) * (p2 - 1);
int y;
// 选择一个与n互质的元素,记为e,求得模反元素d
for (int i = 3; i < m; i += 1331){
int gcd = exgcd(i, m, d, y);
if (gcd == 1 && d > 0){
e = i;
break;
}
}
}
// 快速幂求 a^b % c
int Quick_Pow(int a, int b, int c)
{
int tot = 1;
while (b){
if (b & 1) tot = (1LL * tot * a) % c; //可能会溢出
a = (1LL * a * a) % c;
b >>= 1;
}
return tot;
}
//RSA 加密
void RSA_Encrypt(int e, int n, wstring wstr)
{
int len = wstr.size();
for (int i = 0; i < len; i++){
wfout << Quick_Pow(wstr[i], e, n) << " "; //输出密文
}
wfout << endl;
}
//RSA 解密
void RSA_Decrypt(int d, int n, wstring wstr)
{
wstringstream wss(wstr);
int x;
while (wss >> x){
wfout << (wchar_t)Quick_Pow(x, d, n); //输出解密后的原文对应字符
}
wfout << endl;
}
int main()
{
wstring wstr;
wfin.open("Plain_text.txt");
wfout.open("Cipher_text.txt");
//wfin.imbue(loc); //Linux 下需要
int n, e, d;
RSA_Initialize(n, e, d);
printf("Public Key (e, n) : (%d, %d).\n",e, n);
printf("Private Key (d, n) : (%d, %d).\n\n",d, n);
int Case = 0;
while (getline(wfin, wstr)){
printf("Line %d data is being encrypted.\n",++Case);
RSA_Encrypt(e, n, wstr);
}
wfin.close();
wfout.close();
wfin.open("Cipher_text.txt");
wfout.open("Decrypt_text.txt");
//wfout.imbue(loc); //Linux 下需要
Case = 0;
while (getline(wfin, wstr)){
printf("Line %d data is being decrypted.\n",++Case);
RSA_Decrypt(d, n, wstr);
}
wfin.close();
wfout.close();
}