C++实现维吉尼亚密码加密
- 格式:docx
- 大小:16.29 KB
- 文档页数:3
维吉尼亚算法分析及应用一.实验目的通过应用维吉尼亚算法对数据进行加解密的操作,了解维吉尼亚的加解密的机制,加深对维吉尼亚的算法理解二.试验环境安装Windows操作系统的PC机,具有C语言编译环境三.试验原理加密过程很简单,就是给定密码字母X和明文字母Y,密文字母是位于X行和Y列的那个字母。
这样就决定了加密一天消息与消息一样长的密钥字符串,通常,迷药字符串事是密钥的重复。
使用查表的方式多加密几次就能很轻易的总结出规律:将A-Z以0-25编号,那么加密过程就是,在代换表的第一行中找到消息字母,如W,然后向后移D次(即3次),所得的字母就是密文了。
如果数到末位,那么下一次移位就是从头(即A)继续也就是说,可以将A-Z看成一个环,加密过程就是找到消息字母后,将指针往环的某个特定方向移位,次数就是密钥字母所代表的数字,这其实是一个模26的过程。
扩展一下,以上加密仅能对26个字母进行加密,而且不能区分大小写,但其实英文中除了字母外,还有标点符号,还有空格。
如果考虑到大部分英文字符,那个维吉尼亚代换表将比较大,而且有点浪费空间,如果能将被加密的字符有N个如果把这N个字符建成一个环,那么加密过程即使模N的过程,即C(I)=K(I)+P(I)modN,其中,K,C,P分别代表的是密钥空间,密文空间,消息(明文)空间。
四.主要代码#include <iostream.h>#include <stdio.h>#include <string.h>char Vigenere(char m,char k){if (m==' ') return m;else{if (m>=65&&m<=90)m=m+32;m=((m-97)+(k-97));if (m>25)m=m%26;m=m+97;return m;}}void main(){char *key;char *d;char *m;m=new char[100];d=new char[100];key=new char[100];printf("please input plaintext:"); gets(m);printf("please input key:");gets(key);int len=strlen(m);int len_k=strlen(key);printf("the encode is:");for(int i=0,j=0;i<len;i++,j++){if (j>=len_k)j=j%len_k;d[i]=Vigenere(m[i],key[j]);cout<<d[i];}cout<<endl;}五.运行结果。
一、实验目的1. 理解维吉尼亚密码的原理和加密解密过程。
2. 掌握维吉尼亚密码的编程实现。
3. 破解维吉尼亚密码,提高密码学应用能力。
二、实验原理维吉尼亚密码是一种多表密码,它通过将明文与密钥进行组合,实现字符的替换加密。
加密过程中,密钥的长度决定了密钥表的大小,密钥表中的每一行对应一个密钥,加密时按照密钥表中的行进行替换。
解密过程则是加密过程的逆过程。
三、实验内容1. 维吉尼亚密码的加密与解密实现(1)加密① 创建密钥表:根据密钥长度生成密钥表,密钥表中每一行对应一个密钥,密钥长度等于明文长度。
② 对明文进行加密:将明文中的每个字符按照密钥表中的行进行替换,得到密文。
(2)解密① 创建密钥表:根据密钥长度生成密钥表。
② 对密文进行解密:将密文中的每个字符按照密钥表中的行进行替换,得到明文。
2. 维吉尼亚密码的破解(1)重合指数法① 计算密文的重合指数:将密文与英文常见单词的重合指数进行比较,选择重合指数最高的密钥长度。
② 遍历密钥长度:对于每个密钥长度,遍历26个可能的偏移量,计算重合指数,选择重合指数最高的偏移量。
③ 解密密文:根据密钥长度和偏移量,对密文进行解密,得到可能的明文。
(2)暴力破解法① 遍历密钥长度:遍历所有可能的密钥长度。
② 遍历密钥:对于每个密钥长度,遍历所有可能的密钥。
③ 解密密文:根据密钥长度和密钥,对密文进行解密,得到可能的明文。
四、实验步骤1. 创建密钥表根据密钥长度生成密钥表,密钥表中每一行对应一个密钥。
2. 加密明文将明文中的每个字符按照密钥表中的行进行替换,得到密文。
3. 解密密文将密文中的每个字符按照密钥表中的行进行替换,得到明文。
4. 破解密文(1)重合指数法① 计算密文的重合指数。
② 遍历密钥长度。
③ 遍历密钥。
④ 解密密文。
(2)暴力破解法① 遍历密钥长度。
② 遍历密钥。
③ 解密密文。
五、实验结果与分析1. 加密与解密实验结果表明,维吉尼亚密码的加密和解密过程能够正确实现,密文与明文能够成功还原。
Vigenere算法实现传统加密技术对于当今的网络安全发挥不了大作用,但每一本讲述密码学的书的开头都会率先介绍它们,因为它们是密码学的基础,是密码学的历史。
Vigenere密码就是一种传统加密技术,它是多表代换密码,能够有效改进单表代换密码的词频分布特征问题。
详细介绍请参考密码学相关书籍。
几乎每一本密码学的书在讲述Vigenere密码的章节都会有这么一个《Vigenere代换表》用户讲解Vigenere密码机制:ABCDEFGHIJKLMNOPQRSTUVWXYZBCDEFGHIJKLMNOPQRSTUVWXYZACDEFGHIJKLMNOPQRSTUVWXYZABDEFGHIJKLMNOPQRSTUVWXYZABCEFGHIJKLMNOPQRSTUVWXYZABCDFGHIJKLMNOPQRSTUVWXYZABCDEGHIJKLMNOPQRSTUVWXYZABCDEFHIJKLMNOPQRSTUVWXYZABCDEFGIJKLMNOPQRSTUVWXYZABCDEFGHJKLMNOPQRSTUVWXYZABCDEFGHIKLMNOPQRSTUVWXYZABCDEFGHIJLMNOPQRSTUVWXYZABCDEFGHIJKMNOPQRSTUVWXYZABCDEFGHIJKLNOPQRSTUVWXYZABCDEFGHIJKLMOPQRSTUVWXYZABCDEFGHIJKLMNPQRSTUVWXYZABCDEFGHIJKLMNOQRSTUVWXYZABCDEFGHIJKLMNOPRSTUVWXYZABCDEFGHIJKLMNOPQSTUVWXYZABCDEFGHIJKLMNOPQRTUVWXYZABCDEFGHIJKLMNOPQRSUVWXYZABCDEFGHIJKLMNOPQRSTVWXYZABCDEFGHIJKLMNOPQRSTUWXYZABCDEFGHIJKLMNOPQRSTUVXYZABCDEFGHIJKLMNOPQRSTUVWYZABCDEFGHIJKLMNOPQRSTUVWXZABCDEFGHIJKLMNOPQRSTUVWXY加密过程很简单,就是给定密钥字母x和明文字母y,密文字母是位于x行和y列的那个字母。
实验一维吉尼亚一、实验目的通过实验掌握维吉尼亚算法,对维吉尼亚加深认识。
二、实验要求用VC 编程实现,密钥是自己名字的全拼,明文是MINGMAXUEKECHENG,通过程序实现求出密文。
三、实验环境安装Windows操作系统的PC机,具有C语言编译环境。
四、实验内容vigenere方阵明文a b c d e f g h i j k l m n o p q r s t u v w x y za abcdefghijklmnopqrstuvwxy zb bcdefghijklmnopqrstuvwxyz ac cdefghijklmnopqrstuvwxyz a bd defghijklmnopqrstuvwxyz a b ce efghijklmnopqrstuvwxyz a b c d………z z a b c d e f g h i j k l m n o p q r s t u v w x y源代码:#include "iostream"#include "string"using namespace std;int createVigenere(char vigenere[][26]){for(int i=0;i<26;i++){if(i>0)vigenere[0][i] = vigenere[0][i-1] + 1;elsevigenere[0][i] = 'A';for(int j=1;j<26;j++){if(vigenere[j-1][i]<'Z')vigenere[j][i] = vigenere[j-1][i] +1;elsevigenere[j][i] = vigenere[j-1][i] - 25;}}return 1;}void encrepty(char vigenere[][26],char* source,char* key,char *cipher) {source = strlwr(source);//将大写转换为小写char *p = strlwr(key);char *q = source;char *s = cipher;while(*q != '\0'){while(*p !='\0'&&*q != '\0'){if(*q<'a'||*q>'z')//如果要加密的字符中不是26个字母则将其保存,不为其加密{*s = *q;q++;s++;continue;}*s = vigenere[*q-97][*p-97];//密钥*p-97,密文*q-97s++;p++;q++;}p = key;}*s = '\0';}void deciphring(char vigenere[][26],char* cipher,char* key,char *source) {cipher = strlwr(cipher);char *p = strlwr(key);char *q = cipher;char *s = source;while(*q != '\0'){while(*p !='\0'&&*q!='\0')//如果要加密的字符中不是26个字母则将其保存,不为其解密{if(*q<'a'||*q>'z'){*s = *q;q++;s++;continue;}*s = vigenere[0][(*q-*p+26)%26]+32;s++;p++;q++;}p = key;}*s = '\0';}void main(){char source[1024]={'\0'};//明文char cipher[1024]={'\0'};//密文char key[26] = "lijaixi";//密匙int index[1024] = {0};//标识明文的大小写char vigenere[26][26]={0};//vigenere加密矩阵createVigenere(vigenere);//创建加密矩阵/* for(i=0;i<26;i++)//输出加密矩阵{for(int j=0;j<26;j++){cout<<vigenere[i][j]<<" ";}cout<<endl;}*/cout<<"请输入要加密的字符串:"<<endl;gets(source);char *p = source;int i = 0;while(*p != '\0')//确定明文中大写字母的位置{if(*p>='A'&&*p<='Z'){index[i++] = 1;//如果输入的字母为大写则对应位置保存为1否则为0}else{index[i++] = 0;}p++;}encrepty(vigenere,source,key,cipher);//加密cout<<"加密结果为:";cout<<cipher<<endl;char yy[1024];cout<<"解密结果为:";deciphring(vigenere,cipher,key,yy);//解密p = yy;//加密转换后的结果却是大写i = 0;while(*p != '\0'){if(index[i++] == 1)//如果原来是小写则需要将转换都的大写转换为小写{*p = *p-32;}p++;}cout<<yy<<endl;}运行结果如下图:五、心得体会Vigenere密码比较简单,通过实验更使我明白了密码的加密和加密过程,对它的程序实现方法有了更为深刻的了解。
仿射密码算法与维基尼亚算法实验2.1 仿射密码加密解密算法一、源程序#include#include#include#includeint gcd(int a, int b)/*辗转相除法求a,b的最大公因数*/{int k = 0;do{k = a%b;a = b;b = k;}while(k!=0);return a;}int Ni(int a, int b) /*求a相对于b的逆*/{int i = 0;while(a*(++i)%b!=1);return i;}void Affine_enc() //加密{char c[100];int length, i=0, ka=0, kb=0, tmp;printf("****************欢迎使用Affine加密算法****************\请输入明文: ");gets(c);length = strlen(c);printf("请输入密钥(2 numbers): ");scanf("%d%d", &ka, &kb);getchar();if(gcd(ka,26)!=1){printf("The value of the key is error!\Press any key to return...");return;}for(i=0; i<="" p="">{if(c[i]>96&&c[i]<123)c[i] = (ka*(c[i]-97)+kb)%26+65;else if(c[i]>64&&c[i]<91)c[i] = (ka*(c[i]-65)+kb)%26+65;}printf("经加密后的密文为: %s\", c);printf("Press any key to return...");getch();}void Affine_dec() //解密{char c[100];int length, i=0, ka=0, kb=0, tmp;printf("****************欢迎使用Affine解密算法****************请输入密文: ");gets(c);length = strlen(c);printf("请输入密钥(2 numbers): ");scanf("%d%d", &ka, &kb);getchar();if(gcd(ka,26)!=1){printf("The value of the key is error!\Press any key to return...");return;}for(i=0; i<="" p="">{if(c[i]>64&&c[i]<91){tmp = Ni(ka,26)*((c[i]-65)-kb);if(tmp<0)c[i] = tmp%26+26+97;elsec[i] = tmp%26+97;}}printf("\经解密后的原明文为:\%s\", c);printf("Press any key to return...");getch();}void main(){char i = '0';while(i!='3'){printf("\\\\\欢迎使用Affine密码系统:\\");printf("\\-------加密请输入1\解密请输入2\退出系统请输入0------\\");printf("********************Press 1~3 to choose:********************\");i = getch();if(i=='1')Affine_enc();else if(i=='2')Affine_dec();else if(i=='3')break;}}二、实验效果图2.1仿射密码加密算法效果图:2.2仿射密码解密算法效果图:实验2.2 维基尼亚算法一、源程序#include#include#includevoid main(){char c1[26],c2[26][26],str[100],k[26];int i,j,d,len,l[26],m;for(i=0;i<26;i++)c1[i]=i+65;for(i=0;i<26;i++)for(j=0;j<26;j++)c2[i][j]=(i+j)%26+65;printf("\\\\\欢迎使用Vigenere密码系统:\\");printf("\\-------加密请输入1\解密请输入2\退出系统请输入0------");do{printf("\\请选择:");scanf("%d",&d);switch(d){case 1:{printf("\请输入密钥:");scanf("%s",k);len=strlen(k);strupr(k);for(i=0;i<len;i++)< bdsfid="202" p=""></len;i++)<>for(j=0;j<26;j++)if(k[i]==c1[j])l[i]=j;printf("\请输入明文:");scanf("%s",str);strupr(str);printf("\密文为:");for(i=0;str[i]!='\\0';i++)for(j=0;j<26;j++)if(str[i]==c1[j]){m=i%len;printf("%c",c2[l[m]][j]);if(i!=0 && m==(len-1))printf(" ");break;}break;}case 2:{printf("\请输入密钥:");scanf("%s",k);len=strlen(k);strupr(k);for(i=0;i<len;i++)< bdsfid="229" p=""></len;i++)<> for(j=0;j<26;j++)if(k[i]==c1[j])l[i]=j;printf("\输入密文:");scanf("%s",str);strupr(str);printf("\明文为:");for(i=0;i< bdsfid="238" p=""><>for(j=0;j<26;j++){m=i%len;if(str[i]==c2[l[m]][j]){printf("%c",c1[j]+32);break;}}break;}case 0:exit(0);default: printf("\请重新输入:\"); }}while(d);printf("\");}二、实验效果图2.1维吉尼亚加密算法效果图:2.2维吉尼亚解密算法效果图:。
维吉尼亚密码c语言源代码#include<stdio.h> // 头文件<stdio.h> , 声明标准输入输出函数#include<string.h> // 头文件<string.h> ,声明字符串操作函数char vigenere_table[26][26]; //定义维吉尼亚表void set_vigenere_table(){int i,j;int key; //行指针for (i = 0; i < 26; i++){key=i;for(j=0;j<26;j++){vigenere_table[i][j]='A'+(key%26);key++;}}printf("初始化维吉尼亚表完毕:\n\n");}void vigenere_encrypt(char* source,char* des) //定义加密函数{int source_len=strlen(source);int key_len=strlen(des);int i;for(i=0;i<source_len;i++) //对每个字母进行加密{int source_index= source[i]-'A'; //密文指针int key_index=des[i%key_len]-'A'; //维吉尼亚表指针int des_index=vigenere_table[key_index][source_index]-'A';des[i]=des_index+'A';}des[source_len]='\0';}void vigenere_decrypt(char* source,char* des) //定义解密函数{#define MAX_LEN 26int source_len=strlen(source);int key_len=strlen(des);int i;for(i=0;i<source_len;i++) //对每个字母进行解密{int key_index=des[i%key_len]-'A'; //维吉尼亚表指针int j;for(j=0;j<MAX_LEN;j++) //从维吉尼亚表中查找密文指针{if(vigenere_table[key_index][j]==source[i]){break;}}des[i]=j+'A';}des[source_len]='\0';}int main(){char plain[]="VIGENERECIPHER";char key[]="ABCD";char result[20];char result1[20];set_vigenere_table();vigenere_encrypt(plain,result);printf("明文: %s\n密钥: %s\n密文: %s\n",plain,key,result);vigenere_decrypt(result,result1);printf("解密后: %s\n",result1);return 0;}。
C语言Vigenère密码的综合题一、概述Vigenère密码是一种多表密码,是由法国人布拉瓦·德维热纳于1553年发明的。
它是基于字母表的轮换和偏移来实现加密与解密的。
Vigenère密码算法的核心思想是使用一个密钥串来进行加密和解密操作,相比传统的凯撒密码,Vigenère密码更加安全可靠。
在C语言中实现Vigenère密码算法可以帮助我们更好地了解密码学和算法设计的相关知识。
二、Vigenère密码的原理Vigenère密码算法的核心原理是利用关键词对明文进行分组加密,具体步骤如下:1.确定关键词,将明文和关键词转换为阿拉伯数字表达方式。
2.将关键词复制至与明文长度相等的长度。
3.按照两者的数值进行加法计算。
4.将计算结果对26取模。
5.将计算结果转换为字符形式。
6.将加密后的字符拼接成密文。
三、Vigenère密码的具体实现在C语言中实现Vigenère密码算法需要考虑以下几个关键步骤:1. 输入明文和关键词。
2. 将明文和关键词转换为阿拉伯数字表达方式。
3. 判断明文和关键词的长度以便确定循环加密。
4. 进行加密计算。
5. 输出密文。
四、示例代码下面是一个简单的C语言示例代码,实现了Vigenère密码的加密操作:```c#include <stdio.h>#include <string.h>void encrypt(char* pl本人n, char* key) {int plen = strlen(pl本人n);int klen = strlen(key);for (int i = 0; i < plen; i++) {pl本人n[i] = ((pl本人n[i] - 'A' + key[i klen] - 'A') 26) + 'A'; }}int m本人n() {char pl本人n[100];char key[100];printf("请输入明文:");scanf("s", pl本人n);printf("请输入关键词:");scanf("s", key);encrypt(pl本人n, key);printf("加密后的密文为:s\n", pl本人n);return 0;}```五、总结Vigenère密码算法是一种经典的密码算法,通过使用关键词对明文进行分组加密,可以有效提高密码的安全性。
一、实验目的1. 理解维吉尼亚密码的原理和加密、解密过程。
2. 掌握使用维吉尼亚密码进行加密和解密的方法。
3. 通过实验加深对古典密码学中维吉尼亚密码的理解。
二、实验原理维吉尼亚密码是一种多表代换密码,由密钥控制明文与密文的转换。
其加密和解密过程如下:1. 加密过程:(1)将密钥与明文进行对齐,不足部分进行循环。
(2)根据密钥在密表中找到对应的列,密表中每列对应一个字母。
(3)将明文中的每个字母替换成密表中对应列的字母。
2. 解密过程:(1)将密钥与密文进行对齐,不足部分进行循环。
(2)根据密钥在密表中找到对应的列,密表中每列对应一个字母。
(3)将密文中的每个字母替换成密表中对应列的字母,还原出明文。
三、实验环境1. 操作系统:Windows 102. 编程语言:Python3.83. 工具:Jupyter Notebook四、实验步骤1. 编写加密函数```pythondef vigenere_encrypt(plain_text, key):key = key.upper()plain_text = plain_text.upper()key_length = len(key)key_list = list(key)cipher_text = ''for i, char in enumerate(plain_text):if char.isalpha():key_index = key_list[i % key_length]key_offset = ord(key_index) - ord('A')cipher_char = chr((ord(char) - ord('A') + key_offset) % 26 + ord('A'))cipher_text += cipher_charelse:cipher_text += charreturn cipher_text```2. 编写解密函数```pythondef vigenere_decrypt(cipher_text, key):key = key.upper()cipher_text = cipher_text.upper()key_length = len(key)key_list = list(key)plain_text = ''for i, char in enumerate(cipher_text):if char.isalpha():key_index = key_list[i % key_length]key_offset = ord(key_index) - ord('A')plain_char = chr((ord(char) - ord('A') - key_offset) % 26 + ord('A'))plain_text += plain_charelse:plain_text += charreturn plain_text```3. 编写主函数```pythondef main():plain_text = input("请输入明文:")key = input("请输入密钥:")cipher_text = vigenere_encrypt(plain_text, key)print("加密后的密文为:", cipher_text)decrypted_text = vigenere_decrypt(cipher_text, key)print("解密后的明文为:", decrypted_text)if __name__ == "__main__":main()```4. 运行实验程序,输入明文和密钥,观察加密和解密结果。
运行后先输入密钥,再输入文件名(输入文本,和输出文本的),文件名和代码在同一目录下不用加路径。
头文件: vi.h
#ifndef _VI_H
#define_VI_H
#include<iostream>
#include<string>
class vi
{
private:
std::string key;
public:
void setkey();
void job();
};
#endif
#include"vi.h"
#include<iostream>
#include<fstream>
#include<string>
using namespace std;
void vi::setkey()
{
getline(cin,key,'\n');
}
void vi::job()
{
string s,k;
cout<<"需要加密的文件名:"<<endl;
getline(cin,s,'\n');
ifstream in(s.c_str());
cout<<"存放密文的文件名:"<<endl;
getline(cin,k,'\n');
ofstream out(k.c_str());
char ch;
unsigned char n;
int i=0;
while((ch=in.get())!=EOF)
{
if(ch>='a'&&ch<='z')
{
n=ch+key[i]-97;
if(n>122)
{
n-=26;
out.put(n);
}
else out.put(n);
}
else if(ch>='A'&&ch<='Z')
{
n=ch+key[i]-65;
if(n>122)
{
n-=26;
out.put(n);
}
else out.put(n);
}
else
{
out.put(ch);
continue;
}
i=(i+1)%5;
}
}
#include"vi.h"
#include<iostream>
using namespace std;
int main(int argc, char *argv[]) { vi j;
j.setkey();
j.job();
return 0;
}。