C語(yǔ)言實(shí)現(xiàn)維吉尼亞密碼的示例代碼
前言
作業(yè)要求:明文中的空格在密文中也有對(duì)應(yīng)空格,明文中的大小寫在密文中也有對(duì)應(yīng)大小寫。
一、維吉尼亞(Vigenère)密碼原理及介紹
在一個(gè)凱撒密碼中,字母表中的每一字母都會(huì)作一定的偏移,例如偏移量為3時(shí),A就轉(zhuǎn)換為了D、B轉(zhuǎn)換為了E……而維吉尼亞密碼則是由一些偏移量不同的愷撒密碼組成。
在生成密碼的時(shí)候,可以通過(guò)查表的方式(維吉尼亞密碼表),通過(guò)密鑰,來(lái)確定明文所對(duì)應(yīng)的密文。
這一表格包括了26行字母表,每一行都由前一行向左偏移一位得到。
例如,假設(shè)明文為:
GOODSTUDY
密鑰為:
HNUN
由于密鑰比明文短,因此需要重復(fù)密鑰,直至密鑰和明文一樣長(zhǎng)。對(duì)于密鑰來(lái)說(shuō),每個(gè)字母代表的偏移量為該字母在字母表中的位置
對(duì)于第一個(gè)字母G,對(duì)應(yīng)密鑰第一個(gè)字母H,那么由表格中的G行H列加密得到字母N,以此類推,可以得到:
明文:GOODSTUDY 密鑰:HNUN 密文:NBIQZGOQF
二、加密/解密算法介紹
1.加密算法
主要思路:通過(guò)ASCII碼來(lái)計(jì)算偏移量
附ASCII碼對(duì)照表:
代碼如下:
int Encryption(char* Plaintext, char* key) //加密算法 { int i = 0, j = strlen(key), k = strlen(Plaintext),m=0; char result[MAXSIZE] = {0}; for (i = 0; i < k; i++) { if (Plaintext[i] != ' '&& Plaintext[i] >= 'a' && Plaintext[i] <= 'z')//明文是小寫字母 { if (key[m % j] >= 'a' && key[m % j] <= 'z')//密鑰為小寫字母 { result[i] = (Plaintext[i] + key[m % j] - 2 * 'a') % 26 + 'a'; } else if (key[m % j] >= 'A' && key[m % j] <= 'Z')//密鑰為大寫字母 { result[i] = (Plaintext[i] + key[m % j] - 'A'-'a') % 26 + 'a'; } m++; } else if (Plaintext[i] != ' ' && Plaintext[i] >= 'A' && Plaintext[i] <= 'Z')//明文是大寫字母 { if (key[m % j] >= 'a' && key[m % j] <= 'z')//密鑰為小寫字母 { result[i] = (Plaintext[i] + key[m % j] - 'a' - 'A') % 26 + 'A'; } else if (key[m % j] >= 'A' && key[m % j] <= 'Z')//密鑰為大寫字母 { result[i] = (Plaintext[i] + key[m % j] - 'A' - 'A') % 26 + 'A'; } m++; } else result[i] = ' '; } printf("加密后的密文為:%s\n",result); return 0; }
思路介紹:由于要求<明文中的空格在密文中也有對(duì)應(yīng)空格,明文中的大小寫在密文中也有對(duì)應(yīng)大小寫>,所以需要判斷輸入的明文是否有空格符和密鑰中字母的大小寫。
key[m%j]是為了確保在明文/密文比密鑰長(zhǎng)時(shí)重復(fù)密鑰。
2.解密算法
主要思路:加密算法的逆過(guò)程
代碼如下(示例):
int Decrypt(char* Ciphertext, char* key)//解密算法 { int i = 0, j = strlen(key), k = strlen(Ciphertext),m=0; char result[MAXSIZE] = { 0 }; for (i = 0; i < k; i++) { if (Ciphertext[i] != ' ' && Ciphertext[i] >= 'a' && Ciphertext[i] <= 'z')//明文是小寫字母 { if (key[m % j] >= 'a' && key[m % j] <= 'z')//密鑰為小寫字母 { result[i] = (Ciphertext[i] + 26 - (key[m % j] - 'a') - 'a') % 26 + 'a'; } else if (key[m % j] >= 'A' && key[m % j] <= 'Z')//密鑰為大寫字母 { result[i] = (Ciphertext[i] + 26 - (key[m % j] - 'A') - 'a') % 26 + 'a'; } m++; } else if (Ciphertext[i] != ' ' && Ciphertext[i] >= 'A' && Ciphertext[i] <= 'Z')//明文是大寫字母 { if (key[m % j] >= 'a' && key[m % j] <= 'z')//密鑰為小寫字母 { result[i] = (Ciphertext[i] + 26 - (key[m % j] - 'a') - 'A') % 26 + 'A'; } else if (key[m % j] >= 'A' && key[m % j] <= 'Z')//密鑰為大寫字母 { result[i] = (Ciphertext[i] + 26 - (key[m % j] - 'A') - 'A') % 26 + 'A'; } m++; } else result[i] = ' '; } printf("解密后的明文為:%s\n", result); return 0; }
三、完整代碼展示
#include <stdio.h> #include <string.h> #define MAXSIZE 100 #define KEY 50 int Encryption(char* Plaintext, char* key) //加密算法 { int i = 0, j = strlen(key), k = strlen(Plaintext),m=0; char result[MAXSIZE] = {0}; for (i = 0; i < k; i++) { if (Plaintext[i] != ' '&& Plaintext[i] >= 'a' && Plaintext[i] <= 'z')//明文是小寫字母 { if (key[m % j] >= 'a' && key[m % j] <= 'z')//密鑰為小寫字母 { result[i] = (Plaintext[i] + key[m % j] - 2 * 'a') % 26 + 'a'; } else if (key[m % j] >= 'A' && key[m % j] <= 'Z')//密鑰為大寫字母 { result[i] = (Plaintext[i] + key[m % j] - 'A'-'a') % 26 + 'a'; } m++; } else if (Plaintext[i] != ' ' && Plaintext[i] >= 'A' && Plaintext[i] <= 'Z')//明文是大寫字母 { if (key[m % j] >= 'a' && key[m % j] <= 'z')//密鑰為小寫字母 { result[i] = (Plaintext[i] + key[m % j] - 'a' - 'A') % 26 + 'A'; } else if (key[m % j] >= 'A' && key[m % j] <= 'Z')//密鑰為大寫字母 { result[i] = (Plaintext[i] + key[m % j] - 'A' - 'A') % 26 + 'A'; } m++; } else result[i] = ' '; } printf("加密后的密文為:%s\n",result); return 0; } int Decrypt(char* Ciphertext, char* key)//解密算法 { int i = 0, j = strlen(key), k = strlen(Ciphertext),m=0; char result[MAXSIZE] = { 0 }; for (i = 0; i < k; i++) { if (Ciphertext[i] != ' ' && Ciphertext[i] >= 'a' && Ciphertext[i] <= 'z')//明文是小寫字母 { if (key[m % j] >= 'a' && key[m % j] <= 'z')//密鑰為小寫字母 { result[i] = (Ciphertext[i] + 26 - (key[m % j] - 'a') - 'a') % 26 + 'a'; } else if (key[m % j] >= 'A' && key[m % j] <= 'Z')//密鑰為大寫字母 { result[i] = (Ciphertext[i] + 26 - (key[m % j] - 'A') - 'a') % 26 + 'a'; } m++; } else if (Ciphertext[i] != ' ' && Ciphertext[i] >= 'A' && Ciphertext[i] <= 'Z')//明文是大寫字母 { if (key[m % j] >= 'a' && key[m % j] <= 'z')//密鑰為小寫字母 { result[i] = (Ciphertext[i] + 26 - (key[m % j] - 'a') - 'A') % 26 + 'A'; } else if (key[m % j] >= 'A' && key[m % j] <= 'Z')//密鑰為大寫字母 { result[i] = (Ciphertext[i] + 26 - (key[m % j] - 'A') - 'A') % 26 + 'A'; } m++; } else result[i] = ' '; } printf("解密后的明文為:%s\n", result); return 0; } int main() { int n; char Plaintext[MAXSIZE] = {0}; char Ciphertext[MAXSIZE] = {0}; char key[KEY] = {0}; while (1) { printf("===============\n"); printf(" 1.加密\n"); printf(" 2.解密\n"); printf(" 0.退出\n"); printf("===============\n"); printf("請(qǐng)輸入要執(zhí)行的操作:"); scanf_s("%d",&n); getchar(); switch (n) { case 1: printf("請(qǐng)輸入明文:"); scanf_s("%[^\n]", Plaintext, MAXSIZE); getchar(); printf("請(qǐng)輸入密鑰:"); scanf_s("%[^\n]", key, KEY); Encryption(Plaintext, key); break; case 2: printf("請(qǐng)輸入密文:"); scanf_s("%[^\n]", Ciphertext, MAXSIZE); getchar(); printf("請(qǐng)輸入密鑰:"); scanf_s("%[^\n]", key, KEY); Decrypt(Ciphertext, key); break; case 0: exit(0); break; } } return 0; }
做了一個(gè)菜單方便選擇加密解密。
總結(jié)
主要是ASCII碼的運(yùn)用,對(duì)照維吉尼亞密碼表算出每個(gè)字母的偏移量,對(duì)邏輯要求可能比較高,需要,計(jì)算偏移量以及循環(huán)密鑰較為繁瑣。
到此這篇關(guān)于C語(yǔ)言實(shí)現(xiàn)維吉尼亞密碼的示例代碼的文章就介紹到這了,更多相關(guān)C語(yǔ)言維吉尼亞密碼內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
C++ LeetCode1780判斷數(shù)字是否可以表示成三的冪的和
這篇文章主要為大家介紹了C++ LeetCode1780判斷數(shù)字是否可以表示成三的冪的和題解示例,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-12-12c語(yǔ)言實(shí)現(xiàn)系統(tǒng)時(shí)間校正工具代碼分享
這篇文章主要介紹了c語(yǔ)言實(shí)現(xiàn)系統(tǒng)時(shí)間校正工具,大家參考使用吧2014-01-01OpenCV + MFC實(shí)現(xiàn)簡(jiǎn)單人臉識(shí)別
這篇文章主要為大家詳細(xì)介紹了OpenCV + MFC實(shí)現(xiàn)簡(jiǎn)單人臉識(shí)別,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2019-08-08