|
論壇說明 |
歡迎您來到『史萊姆論壇』 ^___^ 您目前正以訪客的身份瀏覽本論壇,訪客所擁有的權限將受到限制,您可以瀏覽本論壇大部份的版區與文章,但您將無法參與任何討論或是使用私人訊息與其他會員交流。若您希望擁有完整的使用權限,請註冊成為我們的一份子,註冊的程序十分簡單、快速,而且最重要的是--註冊是完全免費的! 請點擊這裡:『註冊成為我們的一份子!』 |
|
主題工具 | 顯示模式 |
2006-05-29, 09:58 AM | #1 |
榮譽會員
|
軟體 - 凱撒加密與解密程式實現
對於此類文章網上已經有很多了,但還是自己試著寫了個,本文同時提供了加密和解密函數,由於本人對密碼學也不是很清除,程式寫得也不咋地,有不妥的地方還望指出.
在程式輸出過程中,把密文中的各個字母的統計訊息也印表出來了,數組元素num[0]----num[25]對應與字母A---Z。 以下程式在VC6.0下編譯通過。 源程式: CODE: // 愷撒加密解密小程式 // 作者:kvew www.smatrix.org // #include <stdio.h> #include <stdlib.h> #include <stdlib.h> void kaiser(int n){ unsigned char ch; FILE *fp1,*fp2; if((fp1=fopen("a.txt","r"))==NULL){ //以讀的方式打開文件a.txt printf("can not open the file a.txt!\n"); exit(0); } if((fp2=fopen("kaiser.txt","w"))==NULL){ //以寫的方式打開b.txt printf("can not open the file b.txt!\n"); exit(0); } while(!feof(fp1)){ ch = fgetc(fp1); if(ch>=65&&ch<=90){ //如果是大寫字母 ch = ch + n; //移位 if(ch>=91) //移位後仍然在大寫字母集中,直接返回 ch = ch%90+64; //超出則轉換下 } else if(ch>=97&&ch<=122){ //如果是小寫字母 ch = ch + n; //移位 if(ch>=123) //移位後仍然在小寫字母集,直接返回 ch = ch%122+96; //超出則轉換下 } fputc(ch,fp2); //如果是其他字元,則不加密照常輸出 } if(fclose(fp1)){ //關閉文件a.txt printf("Can not close the file!\n"); } if(fclose(fp2)){ //關閉文件kaiser.txt printf("Can not close the file!\n"); } } void break_kaiser(){ int i,count,k; int key; int num[26] = {0}; //初始化數組,該數組用來統計密文中各個字母的出現次數 unsigned char ch,ch_b; // num[0]-----num[25]對應字母A--Z FILE *fp1,*fp2; if((fp1=fopen("kaiser.txt","r"))==NULL){ //以讀的方式打開文件a.txt printf("can not open the file a.txt!\n"); exit(0); } if((fp2=fopen("out.txt","w"))==NULL){ //以寫的方式打開b.txt printf("can not open the file b.txt!\n"); exit(0); } while(!feof(fp1)){ ch = fgetc(fp1); if(ch>=65&&ch<=90){ num[ch-65]++; } else if(ch>=97&&ch<=122){ num[ch-97]++; } } if(fclose(fp1)){ //關閉目標文件a.txt printf("Can not close the file!\n"); } count = num[0]; for(i=0;i<26;i++){ printf("the num[%d] is %d\n",i,num); //印表出統計訊息 if(count<num) { count = num; k = i; //記錄下最大值的下標 } } printf("\n\nthe max is %d and its index is %d\n",count,k); ch_b = 65 + k; // 記錄下出現次數最多的字元,以大寫方式記錄 printf("the ch_b is %d\n",ch_b); key = ch_b - 69; //和 E 值相減,計算出key if(key<0) key = 26 + key; printf("the key is: %d\n",key); if((fp1=fopen("kaiser.txt","r"))==NULL){ //再次以讀的方式打開文件a.txt printf("can not open the file a.txt!\n"); exit(0); } while(!feof(fp1)){ //如果沒有讀到文件結尾,那麼繼續讀取 ch = fgetc(fp1); if(ch>=65&&ch<=90){ ch = ch - key; if(ch < 65) ch = 90 - (64 - ch); } if(ch>=97&&ch<=122){ ch = ch - key; if(ch < 97) ch = 122 - (96 - ch); } fputc(ch,fp2); } if(fclose(fp2)){ //關閉文件b.txt printf("Can not close the file!\n"); } } int main(){ int n; printf("***********************************************************\n"); printf("* *\n"); printf("* this program will encrypt the file a.txt to kaiser.txt! *\n"); printf("* and then decrypt kaiser.txt to out.txt *\n"); printf("* *\n"); printf("***********************************************************\n\n"); printf("\nplease input the key number (0--25):\n"); scanf("%d",&n); kaiser(n); printf("encrypted success!\n\n"); // printf("密文中各字母出現次數的統計訊息入下:\n"); break_kaiser(); printf("creaked success!\n"); return 0; } [Copy to clipboard] 程式有很多不成熟的地方,如果有朋友能提出來的話,非常感謝了:) BTW: 以上僅僅是通過統計規律實現的,如果密文很大,那麼從效率上講還是很吃虧的.所以可以考慮只取文章前面的一小部分,用窮盡法可以很快得出26種'明文',然後從中篩選出key,這個是很容易實現的.有了key之後,解密當然就很簡單了. |
送花文章: 3,
|