C語言實作 RSA的簡單加密解密
RSA我就不普及了,網上都有,現在用我的實驗報告實作一下:
需要的資料有:
兩個大素數p,q;
n=pq;
t=(p-1)(q-1);
公鑰e滿足(e,t)=1;
私鑰d滿足de==1(mod n);
加密公式c=m^e(mod n),c是密文,m是明文;
加密的時候注意明文m<n;
下面再展示一下代碼塊:
//判斷兩個數是不是互素,
void gcd(int p,int q){
int temp1,temp2; //q=temp2*p+temp1 ;
if(q<p){
temp1=p;
p=q;
q=temp1;
}
temp1=q%p,temp2=q/p;
while(temp1!=0){
q=p;p=temp1;
temp1=q%p;temp2=q/p;
}
if(temp1==0&&temp2==q){
printf("符合條件!\n");
}
else{
printf("不符合條件!\n");
}
}
//求e關于模(p-1)(q-1)的逆元d:即私鑰
int extend(int e,int t){
int d;
for(d=0;d<t;d++){
if(e*d%t==1)
return d;
}
}
加密函式中要把符號明文轉換成數字明文才可以加密,加密原理是依次把一個個字母對應的ascii碼加密;加密函式中的加密公式pow(m,e)%n可能會導致溢位,這是解決之后的:
//加密函式
void encrypt(int e,int n){ //自己指定指數e
//先將符號明文轉換成字母所對應的ascii碼,
char mingwen[100]; //符號明文
printf("請輸入明文:\n");
scanf("%s",mingwen); //gets(mingwen);
//gets(mingwen);
changdu=strlen(mingwen);
int ming[strlen(mingwen)]; //定義符號明文
for(int i=0;i<strlen(mingwen);i++){
ming[i]=mingwen[i]; //將字母轉換成對應的ascii碼,
printf("%d",mingwen[i]);
}
printf("\n");
//開始加密
printf("加密開始…………………………\n");
int zhuan=1; //c為加密后的數字密文
for(int i=0;i<strlen(mingwen);i++){
for(int j=0;j<e;j++){
zhuan=zhuan*ming[i]%n;
//zhuan=zhuan%n;
}
c[i]=zhuan;
//printf("%d",mi[i]);
zhuan=1;
}
printf("加密密文為:\n");
for(int i=0;i<strlen(mingwen);i++)
printf("%d",c[i]);
printf("\n加密結束…………………………\n");
}
解決之前的:(只要把大的冪指數計算分開計算就行了)
//以下寫法會導致溢位!
// {
// for(int i=0;i<strlen(mingwen);i++){
// zhuan=pow()
// mi[i]=int(pow(ming[i],e))%n;
// printf("密文為:%d",mi[0]);
// }
// }
// printf("密文為:\n");
// for(int i=0;i<strlen(mingwen);i++){
// printf("%d",mi[i]);
// }
//解密函式
void decrypto(int d,int n){
int de_mingwen[changdu],zhuan1=1;
char de_ming[changdu];
for(int i=0;i<changdu;i++){
for(int j=0;j<d;j++){
zhuan1=zhuan1*c[i]%n;
//zhuan=zhuan%n;
}
de_mingwen[i]=zhuan1;
//printf("%d",mi[i]);
zhuan1=1;
}
printf("解密開始…………………………\n");
printf("解密后的數字明文為:\n");
for(int i=0;i<changdu;i++)
printf("%d",de_mingwen[i]);
printf("\n");
printf("解密后的符號明文為:\n");
for(int i=0;i<changdu;i++){
de_ming[i]=de_mingwen[i];
printf("%c",de_ming[i]);
}
printf("\n解密結束…………………………\n");
}
主函式:
int main(){
int q,p,e,d,n,t,x;
printf("請輸入p:",p);scanf("%d",&p);
printf("請輸入q:",q);scanf("%d",&q);
n=q*p;
t=(q-1)*(p-1);
gcd(p,q);
printf("請輸入一個指數e,使得(e,t)=1:");scanf("%d",&e);
gcd(e,t);
d=extend(e,t);
printf("密鑰為:%d,一定保管好!",d);
printf("\n\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n");
encrypt(e,n);
printf("\n請輸入正確的密鑰,密鑰正確將解密上面的密文:");scanf("%d",&d);
decrypto(d,n);
printf("\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n");
return 0;
}
加密函式encrypt()中輸入明文不能用gets(),因為gets()遇到回車就會結束,這樣單個函式測驗是沒有問題的,但是如果測驗整個程式就會出先還沒有執行函式就結束的情況:

用換成scanf("%s",mingwen),這樣就可以執行啦!

記得加上完整的頭檔案哦!因為我定義了一些全域變數:
#include<stdio.h>
#include<string.h>
int changdu;
int c[100];
小白絕對看懂系列!因為我也很菜,所以會寫得比較詳細,防止我下次看的時候不知道是啥哈哈哈,
整個實驗就是這樣啦,可能寫得有點急,整個程式還是有一些拖沓,里面有些功能還需要優化一下,不過基本功能算是實作啦!
這里有個問題想請教前輩:
怎樣在一個函式中使用指標的方法訪問另一個函式的變數?除了使用全域變數外,希望前輩給個例子,比如解密函式里面訪問加密函式里面的加密后的明文c
還有額外的一個問題:一個函式怎么回傳一個陣列?
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/198665.html
標籤:其他
上一篇:Java 單例模式
下一篇:6.執行緒安全的原子操作
