史萊姆論壇

返回   史萊姆論壇 > 教學文件資料庫 > 應用軟體使用技術文件
忘記密碼?
論壇說明

歡迎您來到『史萊姆論壇』 ^___^

您目前正以訪客的身份瀏覽本論壇,訪客所擁有的權限將受到限制,您可以瀏覽本論壇大部份的版區與文章,但您將無法參與任何討論或是使用私人訊息與其他會員交流。若您希望擁有完整的使用權限,請註冊成為我們的一份子,註冊的程序十分簡單、快速,而且最重要的是--註冊是完全免費的!

請點擊這裡:『註冊成為我們的一份子!』

Google 提供的廣告


 
 
主題工具 顯示模式
舊 2006-05-29, 09:58 AM   #1
psac
榮譽會員
 
psac 的頭像
榮譽勳章
UID - 3662
在線等級: 級別:30 | 在線時長:1048小時 | 升級還需:37小時級別:30 | 在線時長:1048小時 | 升級還需:37小時級別:30 | 在線時長:1048小時 | 升級還需:37小時級別:30 | 在線時長:1048小時 | 升級還需:37小時級別:30 | 在線時長:1048小時 | 升級還需:37小時
註冊日期: 2002-12-07
住址: 木柵市立動物園
文章: 17381
現金: 5253 金幣
資產: 33853 金幣
預設 軟體 - 凱撒加密與解密程式實現

對於此類文章網上已經有很多了,但還是自己試著寫了個,本文同時提供了加密和解密函數,由於本人對密碼學也不是很清除,程式寫得也不咋地,有不妥的地方還望指出.

在程式輸出過程中,把密文中的各個字母的統計訊息也印表出來了,數組元素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之後,解密當然就很簡單了.
psac 目前離線  
送花文章: 3, 收花文章: 1631 篇, 收花: 3205 次
 



發表規則
不可以發文
不可以回覆主題
不可以上傳附加檔案
不可以編輯您的文章

論壇啟用 BB 語法
論壇啟用 表情符號
論壇啟用 [IMG] 語法
論壇禁用 HTML 語法
Trackbacks are 禁用
Pingbacks are 禁用
Refbacks are 禁用


所有時間均為台北時間。現在的時間是 12:05 PM


Powered by vBulletin® 版本 3.6.8
版權所有 ©2000 - 2024, Jelsoft Enterprises Ltd.


SEO by vBSEO 3.6.1