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í)候,可以通過查表的方式(維吉尼亞密碼表),通過密鑰,來確定明文所對(duì)應(yīng)的密文。

這一表格包括了26行字母表,每一行都由前一行向左偏移一位得到。
例如,假設(shè)明文為:
GOODSTUDY
密鑰為:
HNUN
由于密鑰比明文短,因此需要重復(fù)密鑰,直至密鑰和明文一樣長(zhǎng)。對(duì)于密鑰來說,每個(gè)字母代表的偏移量為該字母在字母表中的位置
對(duì)于第一個(gè)字母G,對(duì)應(yīng)密鑰第一個(gè)字母H,那么由表格中的G行H列加密得到字母N,以此類推,可以得到:
明文:GOODSTUDY 密鑰:HNUN 密文:NBIQZGOQF
二、加密/解密算法介紹
1.加密算法
主要思路:通過ASCII碼來計(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.解密算法
主要思路:加密算法的逆過程
代碼如下(示例):
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/C++?Qt?MdiArea?多窗體組件應(yīng)用教程
MDI窗體控件類似于畫布,該控件只具備展示窗體的功能,無(wú)法實(shí)現(xiàn)生成窗體,所以我們需要在項(xiàng)目中手動(dòng)增加自定義的Dialog對(duì)話框,并對(duì)該對(duì)話框進(jìn)行一定的定制,這篇文章主要介紹了C/C++?Qt?MdiArea?多窗體組件應(yīng)用,需要的朋友可以參考下2021-12-12
C語(yǔ)言詳解float類型在內(nèi)存中的存儲(chǔ)方式
在c語(yǔ)言中float函數(shù)是單精度的。它在內(nèi)存中以二進(jìn)制的形式存儲(chǔ)。分為符號(hào)位,階碼與尾數(shù)三部分,下面我們?cè)敿?xì)來了解一下2022-04-04
詳解如何在code block創(chuàng)建一個(gè)C語(yǔ)言的項(xiàng)目
這篇文章主要介紹了詳解如何在code block創(chuàng)建一個(gè)C語(yǔ)言的項(xiàng)目,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2020-12-12

