C语言实现简单的RSA算法
C语言实现简单的RSA算法
实验内容:
1、输入两个素数,然后生成一个随机数,计算出随机数的逆元,然后保存这些信息;
2、选择加密,则输入明文,输出密文;
3、选择解密,则输入密文,输出明文。
(要求有必要的文字说明,比如选取的两个素数,随机数,逆元等都需要显示)
代码:
#include<stdio.h>
#include<stdlib.h>
#include <time.h>
#include<math.h>
char text[100];
int result[100];
int count = 0;
int getNi(int e, int n)//求逆
{
int d;
for (d = 0; d < n; d++) {
if (e * d % n == 1)
return d;
}
}
int Gcd(int a, int b)//求最大公因数
{
if (a % b == 0)
return b;
else;
return Gcd(b, a % b);
}
int getrand(int p,int q){//产生随机数e
int m=(p-1)*(q-1);
int e,c;
while (1 ) {
srand((unsigned)time(NULL));
e = rand() % m;
c = Gcd(e, m);
if (c == 1)
break;
}
return e;
}
//加密
void Encode(int e,int n) {
printf("请输入明文:");
int c = getchar();
while (1) {
if (c == '\n')break;
text[count] = c;
count++;
c = getchar();
}
int flag = 1;
for (int i = 0; i < count; i++) {
for (int j = 0; j < e; j++) {
flag = flag * (int)text[i] % n;
}
result[i] = flag;
flag = 1;
}
printf("\n加密密文为:\n");
for (int i = 0; i < count; i++) {
printf("%d", result[i]);
}
}
//解密
void Decode(int d, int n){
int flag = 1;
int m[100];
for (int i = 0; i < count; i++) {
for (int j = 0; j < d; j++) {
flag = flag * result[i] % n;
}
m[i] = flag;
flag = 1;
}
printf("\n解密明文为:\n");
for (int i = 0; i <count; i++)
printf("%c", m[i]);
}
int main(){
int p,q,n;
printf("请输入两个素数p,q(要求p,q的乘积要大于127):");//ASCII码最大为127
scanf("%d %d",&p,&q);
n=p*q;
int m = (p - 1) * (q - 1);
printf("n=%d",n);
int e;
e = getrand(p, q);
printf("\n公钥e=%d", e);
int d;
d= getNi(e, m);
printf("\n私钥d=%d",d);
int func=0;
while (func != 3) {
printf("\n------------------------------------------");
printf("\n请选择功能:\n");
printf("1、加密\n");
printf("2、解密\n");
printf("3、退出\n");
printf("------------------------------------------\n");
scanf("%d", &func);
getchar();
if (func == 1) {
Encode(e, n);
}
else if (func == 2) {
Decode(d, n);
}
else
return 0;
}
return 0;
}
总结
1、要求输入p,q的乘积需要大于127的原因是ASCII码中最大为127,如果p,q乘积小于某个字符的ASCII码的话,加密结果就会不准确;
2、在加密解密的算法中me及cd都需要用两层for循环嵌套实现,直接使用pow()函数会出现溢出问题;
3、在定义明文,密文数组时需要注意数据类型的区别,储存明文的数组text为char型,储存加密结果为数组result为int型而不能用char型,否则会出现错误;
4、关于getchar()的使用,如果在getchar()之前使用过scnaf的话需要用一个getchar()来取空scanf造成的一个回车符;