close
簡易版Vigenère cipher程式撰寫
維吉尼亞密碼(Vigenère cipher)是由一些偏移量不同的凱撒密碼所組成。
為了生成密碼,需要使用0到9的數字。
例如,假設明文為:
HEISREADING
選擇某一關鍵詞並重複而得到密鑰,如關鍵詞為0471781時,密鑰為:
04717810471
對於明文的第一個字母H,對應密鑰的第一個數字0,首先把H換成0到25的數字的話為7,則密文的第一個字母為: ( 7 + 0 ) mod 26 = 7 ,數字7再換算回英文字母的H。類似地,明文第二個字母為E,對應密鑰的第一個數字4,則密文的第二個字母為: ( 4 + 4 ) mod 26 = 8 ,數字8再換算回英文字母的I。以此類推,可以得到:
明文:HEISREADING
密鑰:04717810471
密文:HIPTYMBDMUH
解密的過程則與加密相反。例如:根據密文第一個字母H所對應的密鑰的第一個數字0,首先把H換成0到25的數字的話為7,則明文的第一個字母為: ( 7 – 0 ) mod 26 = 7 ,數字7再換算回英文字母的H。類似地,密文第二個字母為I,對應密鑰的第一個數字4,則密文的第二個字母為: ( 8 - 4 ) mod 26 = 4 ,數字4再換算回英文字母的E。以此類推便可得到明文。
以算式來寫的話為:
Ci = Pi +ki ( mod 26 )
Pi = Ci - ki ( mod 26 )
以下為程式碼部分:
/* Vigenere cipher */
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
int main(){
char *data; //輸入
char *target=malloc(100 * sizeof(char)); //輸出
int key[7]={0,4,7,1,7,8,1}; //金鑰
FILE *fPtr;
unsigned long leng, count, i;
int ch;
//讀檔
//註:必須先建立source.txt
fPtr = fopen("source.txt", "r");
fseek(fPtr, 0, SEEK_END);
leng = ftell(fPtr);
fseek(fPtr, 0, SEEK_SET);
data = (char *) malloc((leng + 1) * sizeof(char));
fread(data, 1, leng, fPtr);
fclose(fPtr);
data[leng] = '\0';
printf("\n讀入檔案: %s\n\n", data);
printf("請選擇加密或解密 1.加密 2.解密 :");
scanf("%d",&ch);
switch(ch){
case 1:
//轉小寫
count = 0;
for (i=0; i<leng; i++)
if (isalpha(data[i])) data[count++] = tolower(data[i]);
data[count] = '\0';
//printf("\n明文: %s\n\n", data);
// 將字串編碼
i = 0;
while (data[i] != '\0') {
if (isalpha(data[i])){
target[i]=data[i] - 97;
target[i]=(target[i]+key[i%7])%26;
target[i]=target[i]+65;
}
else target[i] = data[i];
i++;
}
target[i] = '\0';
printf("\n密文: %s\n\n", target);
break;
case 2:
//轉大寫
count = 0;
for (i=0; i<leng; i++)
if (isalpha(data[i])) data[count++] = toupper(data[i]);
data[count] = '\0';
//printf("\n密文: %s\n\n", data);
// 將字串編碼
i = 0;
while (data[i] != '\0') {
if (isalpha(data[i])){
target[i]=data[i] - 65;
target[i]=(target[i]+26-key[i%7])%26;
target[i]=target[i]+97;
}
else target[i] = data[i];
i++;
}
target[i] = '\0';
printf("\n明文: %s\n\n", target);
break;
default:
printf("\n錯誤\n");
break;
}
//輸出檔案
fPtr = fopen("result.txt", "w");
fwrite(target, 1, count, fPtr);
fclose(fPtr);
return 0;
}
加密:
解密:
文章標籤
全站熱搜
留言列表