维吉尼亚密码(Vigenere)加密与解密源代码
- 格式:doc
- 大小:25.00 KB
- 文档页数:2
Vigenere 加解密程序制作一、Vigenere密码简介维吉尼亚密码引入了“密钥”的概念,即根据密钥来决定用哪一行的密表来进行替换,以此来对抗字频统计。
实际上,Vigenere密码的代替规则是用明文字母在Vigenere方阵中的列,和密钥字母在Vigenere方阵中的行的交点处的字母来代替该明文字母。
vigenere方阵为:a 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对如下明文加密:TO BE OR NOT TO BE THAT IS THE QUESTION当选定RELATIONS作为密钥时,加密过程是:明文一个字母为T,第一个密钥字母为R,因此可以找到在R行中代替T的为K,依此类推,得出对应关系如下:密钥:RELAT IONSR ELATI ONSRE LATIO NSREL明文:TOBEO RNOTT OBETH ATIST HEQUE STION密文:KSMEH ZBBLK SMEMP OGAJX SEJCS FLZSY解密时利用Vigenere方阵进行反替换!二、程序制作说明本程序通过控制台的方式来实现对用户输入的明文(密文)的加密(解密),在对明文(密文)的加密(解密)时所用的密钥必需保证是一致的。
程序界面为:1、Vigenere方阵的形成Vigenere方阵的形成是在程序的OnInitDialog()函数中调用Vigenre_Array()函数来实现的。
把Vigenere方阵的字母转换为十进制数据进行观察分析可以看出,最大的数是90,并且从左到右是递增的,直到遇到90为止,然后再从数字65开始。
实验二VIGENERE 密码破译实验目的:熟悉vigenere密码加密的密文实验内容及要求:秘钥长度:3~50;明文为普通英文文章(仅含小写字母)实验过程及代码Vignere:'ktbueluegvitnthuexmonveggmrcgxptlyhhjaogchoemq chpdnetxupbqntietiabpsmaoncnwvoutiugtagmmqsxtvxaoniiogta gmbpsmtuvvihpstpdvcrxhokvhxotawswquunewcgxptlcrxtevtubve wcnwwsxfsnptswtagakvoyyak'第一步:位移法求解key的长度这段密文约有200个字母,先假设key<=20位移20次,每次位移后计算与原密文对应相同的字母个数,即s[i]==s[i+j],i为位置,j为位移量cipher=”ktbueluegvitnthuexmonveggmrcgxptlyhhjaogchoemqchpd netxupbqntietiabpsmaoncnwvoutiugtagmmqsxtvxaoniiogtagmbpsmtuvvihpstpdvcrxhokvhxotawswquunewcgxptlcrxtevtubvewcnwwsxfsn ptswtagakvoyyak'deffind_key_length(cipher):'''''shift and fing the most repeats of the cipher''' MAX_LEN_REP = 10shift = [ None ]length = len(cipher)fori in range(1, length//MAX_LEN_REP):repeat = 0for j in range(length):repeat += 1 if cipher[j]==cipher[(j+i)%length] else 0 shift.append(repeat)fori in range(1, length//MAX_LEN_REP):print('{0:2} '.format(i), end='')print()fori in range(1, length//MAX_LEN_REP):print('{0:2} '.format(shift[i]), end='')print()find_key_length(cipher)运行结果如下:从结果可以看出,3 6 8 12 15 重复字母数相对偏高,这些字母的公因子约为3,于是说密钥长度为3的可能性非常大第二步:获取key长度之后,将文本分为key长度份,即s[0],s[3],s[6]……为一份,s[1],s[4],s[7]……为第二份,剩下的为第三份接下来将每份进行频率分析(Frequency Analysis) deffrequency_analysis(cipher, keyLen, k):'''''find the kth part alpha frequency, k in range(keyLen)'''length = len(cipher)keyDict = {}for alpha in range(ord('a'), ord('a')+26):keyDict[chr(alpha)] = 0fori in range(length):keyDict[cipher[i]] += 1 if i % keyLen == k else 0for alpha in range(ord('a'), ord('a')+26):print(' {0} '.format(chr(alpha)), end='')print()for alpha in range(ord('a'), ord('a')+26):print('{0:2} '.format(keyDict[chr(alpha)]), end='') print()frequency_analysis(cipher, 3, 0) #0, 1, 2程序第一部分结果:可以看出 p8, g7, v7, c6 频率较高,而普通英语文本中 e, t, a, i, n, o频率也较高而一份维吉尼亚密码相当于一个凯撒密码,即位移相同字符数那么可以断定明文 -> 密文即为 e ->g, t ->v, a -> c, n->p 所以key的第一个字符为c接下来就是第二第三部分:程序稍作修改frequency_analysis(cipher, 3, 1)frequency_analysis(cipher, 3, 2)运行结果如下:具体判断过程与上面一样,key的第二的字母为a,第三个为t则key为cat既然知道了密钥,那就把明文破译出来吧key = 'cat'defdecoding_vigenere(cipher, key):'''''decoding vigenere cipher with key'''defgetKeyDict(alpha):shift = ord(alpha) - ord('a')keyDict = {}fori in range(ord('a'), ord('a')+26):keyDict[chr(i)] = chr(i + shift) if i + shift <= ord('z') else chr(i + shift -26)#exchang the key and valuekeyDict = dict(map(lambda t:(t[1], t[0]), keyDict.items()))returnkeyDictkeyLen = len(key)cipLen = len(cipher)keyList = [getKeyDict(key[i]) for i in range(keyLen)] plainText = ''fori in range(cipLen):plainText += keyList[i % keyLen][cipher[i]]print(plainText)decoding_vigenere(cipher, key)开始的时候把key算出来直接用了,程序运行的结果就是把密文又加密了一遍在程序中稍作改动,把每个位移的字典key反转(交换键和值),程序运行结果是:看看到底是什么it is essential to seek out enemy agents who have come to conduct espionage against you and to bribe them to serve you give them instructions and care for them thus doubled agents are recruited and used sun tzut heart of war。
VigenereCipher密码解码Vigenere Cipher解密⼀、实验任务Vigenere Cipher加密密⽂如下:KVNIICWZSNOHUNXQGMRNAHUVWPTBWBPKVYPTBASHRZVIIWIBCGJSGEYGFMOAKBTBJKMAQ EGSQJIJHTRGJSFRXTNBVFVCORWGENSIKRRAXVAIHNNZZRRCKMQEGOGRHGJCOYKVNIICWZ SNOHUNXQGMRNACAGLGKMRUKZYFSHZMCEIWNGLGLWBFQTSBVOXZGYCJRFEPWBVRUCAFSHY WFZGFFYEXXWKAGFFJMNEJSNDZRGSUBBRBYBGBKGMPSECHGUIVTJZRQTOESVAMFUQCQVLC OMOQTSNZXJTBCAGRNLIXXVHUGGGNXGHNAVUGVFWKIXWNUHNGIUPMZGGFVAKYBBVGJSURE VHNWALIFGMEXAKRNHREMPZEWGJHURLGTBCSQDCEIULQCAYWYYFGMZOAUTBEQGWQBGQOAB EUBACSHFRRHQFIBQLIFGMEX请写出详细解密过程。
⼆、Vigenere加密与解密Vigenere加密为单表代换密码,其加密过程可表述为:设m是⼀个正整数,定义P=C=K=(Z26)m,对任意的密钥K=(k1,k2,…,k m),定义e K x1,x2,…,x m=(x1+k1,x2+k2,…,x m+k m)和d K y1,y2,…,y m=(y1?k1,y2?k2,…,y m?k m)为Vigenere加密和解密过程,以上所有运算都在(Z26)m 上进⾏。
三、Vigenere密⽂的破译Vigenere解密⾸先在于确定密钥长度m,意⼤利的乔⽡·尼·波塔于1602年⾸先发现Vigenere明/密⽂中重复字母串的距离正好是密钥长度的倍数,这⼀现象称为“合拍”现象。
维吉尼亚(Vigenere)密码算法(Javascript实现加密与解密) 传统加密技术对于当今的⽹络安全发挥不了⼤作⽤,但每⼀本讲述密码学的书的开头都会率先介绍它们,因为它们是密码学的基础,是密码学的历史。
Vigenere密码就是⼀种传统加密技术,它是多表代换密码,能够有效改进单表代换密码的词频分布特征问题。
详细介绍请参考密码学相关书籍。
⼏乎每⼀本密码学的书在讲述Vigenere密码的章节都会有这么⼀个《Vigenere代换表》⽤户讲解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 ZB C D E F G H I J K L M N O P Q R S T U V W X Y Z AC D E F G H I J K L M N O P Q R S T U V W X Y Z A BD E F G H I J K L M N O P Q R S T U V W X Y Z A B CE F G H I J K L M N O P Q R S T U V W X Y Z A B C DF G H I J K L M N O P Q R S T U V W X Y Z A B C D EG H I J K L M N O P Q R S T U V W X Y Z A B C D E FH I J K L M N O P Q R S T U V W X Y Z A B C D E F GI J K L M N O P Q R S T U V W X Y Z A B C D E F G HJ K L M N O P Q R S T U V W X Y Z A B C D E F G H IK L M N O P Q R S T U V W X Y Z A B C D E F G H I JL M N O P Q R S T U V W X Y Z A B C D E F G H I J KM N O P Q R S T U V W X Y Z A B C D E F G H I J K LN O P Q R S T U V W X Y Z A B C D E F G H I J K L MO P Q R S T U V W X Y Z A B C D E F G H I J K L M NP Q R S T U V W X Y Z A B C D E F G H I J K L M N OQ R S T U V W X Y Z A B C D E F G H I J K L M N O PR S T U V W X Y Z A B C D E F G H I J K L M N O P QS T U V W X Y Z A B C D E F G H I J K L M N O P Q RT U V W X Y Z A B C D E F G H I J K L M N O P Q R SU V W X Y Z A B C D E F G H I J K L M N O P Q R S TV W X Y Z A B C D E F G H I J K L M N O P Q R S T UW X Y Z A B C D E F G H I J K L M N O P Q R S T U VX Y Z A B C D E F G H I J K L M N O P Q R S T U V WY Z A B C D E F G H I J K L M N O P Q R S T U V W XZ 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 加密过程很简单,就是给定密钥字母x和明⽂字母y,密⽂字母是位于x⾏和y列的那个字母。
维吉尼亚密码算法// 实验:维吉尼亚密码算法// 姓名: JJCC X// 学号://#include<iostream>using namespace std;#define MINCHAR 32#define CHARSUM 94char table[CHARSUM][CHARSUM];bool Init();bool Encode(char* key, char* source, char* dest);bool Dncode(char* key, char* source, char* dest);int main(){if(!Init()){cout << "初始化错误!" << endl;return 1;}char key[256];char str1[256];char str2[256];int operation;while(1){do{cout << "请选择⼀个操作:1. 加密; 2. 解密; -1. 退出\n";cin >> operation;}while(operation != -1 && operation != 1 && operation != 2);if(operation == -1)return 0;else if(operation == 1)//加密{cout << "请输⼊密钥:";cin >> key;cout << "请输⼊待加密字符串:";cin >> str1;Encode(key, str1, str2);cout << "加密后的字符串:" << str2 << endl;}else if(operation == 2)//解密{cout << "请输⼊密钥:";cin >> key;cout << "请输⼊待解密字符串:";cin >> str1;Dncode(key, str1, str2);cout << "解密后的字符串:" << str2 << endl;}cout << endl;}return 0;}// 初始化维吉尼亚⽅阵bool Init(){int i, j;for(i = 0; i < CHARSUM; i++){for(j = 0; j < CHARSUM; j++){table[i][j] = MINCHAR + (i + j) % CHARSUM;}}return true;}// 加密// key:密钥// source:待加密的字符串// dest:经过加密后的字符串bool Encode(char* key, char* source, char* dest){char* tempSource = source;char* tempKey = key;char* tempDest = dest;do{*tempDest = table[(*tempKey) - MINCHAR][(*tempSource) - MINCHAR]; tempDest++;if(!(*(++tempKey)))tempKey = key;}while(*tempSource++);dest[strlen(source)] = 0;return true;}// 解密// key:密钥// source:待解密的字符串// dest:经过解密后的字符串bool Dncode(char* key, char* source, char* dest){char* tempSource = source;char* tempKey = key;char* tempDest = dest;char offset;do{offset = (*tempSource) - (*tempKey);offset = offset >= 0 ? offset : offset + CHARSUM;*tempDest = MINCHAR + offset;tempDest++;if(!(*(++tempKey)))tempKey = key;}while(*++tempSource);dest[strlen(source)] = 0;return true;}。
实验一维吉尼亚一、实验目的通过实验掌握维吉尼亚算法,对维吉尼亚加深认识。
二、实验要求用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密码比较简单,通过实验更使我明白了密码的加密和加密过程,对它的程序实现方法有了更为深刻的了解。
维吉尼亚密码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;}。
实验报告表格例实验1(Vigenere算法)的源代码如下:#include<iostream>using namespace std;int tt(){chartable[27]={'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','z'};int w,k,q;w=k=q=0;char miyao[10];//={'n','i','c','e','d','a','y'};cout<<"请输入密钥,且密钥的个数小于10个"<<endl;//for(int i=0;i<9;i++)//{cin>>miyao;//w++;char minwen[20],miwen[20];cout<<"请输入需要加密的明文,且明文的长度一次不能超过19个字母"<<endl;//for(int j=0;j<19;j++)cout<<"明文:";cin>>minwen;cout<<"输入的明文加密后的密文如下"<<endl;for(int p=0;minwen[p]!='\0';p++){if(miyao[q]=='\0'){q=0; k=((minwen[p]-97)+(miyao[q]-97))%26;//miwen[p]=table[k];cout<<table[k];}else{k=((minwen[p]-97)+(miyao[q]-97))%26;//miwen[p]=table[k];cout<<table[k];}q++;}cout<<endl;//加密完成,下面是解密的过程;cout<<"如果想解密请输入加密后的密文"<<endl; cout<<"密文:";cin>>miwen;cout<<"解密后的明文如下"<<endl;int t=0;for(int i=0;miwen[i]!='\0';i++){if(miyao[t]=='\0'){t=0;k=(((miwen[i]-97)+26)-(miyao[t]-97))%26;cout<<table[k];}else{k=(((miwen[i]-97)+26)-(miyao[t]-97))%26;cout<<table[k];}t++;}cout<<endl;//cout<<miwen<<endl;//cout<<minwen<<endl;return 0;}int main(){ tt();//char a[8];//for(int i=0;i<7;i++)//cin>>a;//for(int j=0;a[j]!='\0';j++)//cout<<a[j]<<endl;return 0;}实验过程如图所示:实验体会:本次实验是对Vigenere算法的设计,Vigenere算法的原理就是通过26个英文字母之间在密钥的限定下进行转换,而完成的加密。
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密码算法是一种经典的密码算法,通过使用关键词对明文进行分组加密,可以有效提高密码的安全性。
java实现维吉尼亚加密解密算法加密算法程序:public class mtoc{//输⼊明⽂和密钥,⽤输⼊的密钥对明⽂进⾏加密public static void main(String[] args){int i;char[] c=new char[100];char[] k1=new char[100];//输⼊System.out.print("enter a mingwen string:");String m=MyInput.readString();System.out.print("enter a key string:");String k=MyInput.readString();//构造密钥对照表for(i=0;i<k.length();i++){if(k.charAt(i)>='a'&&k.charAt(i)<='z')k1[i]=(char)(k.charAt(i)-97);if(k.charAt(i)>='A'&&k.charAt(i)<='Z')k1[i]=(char)(k.charAt(i)-65);}//加密for(i=0;i<m.length();i++){if(m.charAt(i)>='a'&&m.charAt(i)<='z')c[i]=(char)((m.charAt(i)-97+k1[i%k.length()])%26+97);if(m.charAt(i)>='A'&&m.charAt(i)<='Z')c[i]=(char)((m.charAt(i)-65+k1[i%k.length()])%26+65);}//输出密⽂for(i=0;i<c.length;i++)System.out.print(c[i]);}}解密算法程序:public class ctom{//输⼊密⽂和密钥,⽤密钥对密⽂解密public static void main(String[] args){int i;char[] m=new char[100];char[] k1=new char[100];//输⼊System.out.print("enter the miwen string:");String c=MyInput.readString();System.out.print("enter the key string:");String k=MyInput.readString();//构造密钥对照表for(i=0;i<k.length();i++){if(k.charAt(i)>='a'&&k.charAt(i)<='z')k1[i]=(char)(k.charAt(i)-97);if(k.charAt(i)>='A'&&k.charAt(i)<='Z')k1[i]=(char)(k.charAt(i)-65);}//解密for(i=0;i<c.length();i++){if(c.charAt(i)>='a'&&c.charAt(i)<='z')m[i]=(char)((c.charAt(i)-97-k1[i%k.length()]+26)%26+97);if(c.charAt(i)>='A'&&c.charAt(i)<='Z')m[i]=(char)((c.charAt(i)-65-k1[i%k.length()]+26)%26+65);}//输出明⽂for(i=0;i<m.length;i++)System.out.print(m[i]);}}需要⽤到的MyInput.java类:// MyInput.java: Contain the methods for reading int, double, and// string values from the keyboardimport java.io.*;public class MyInput{// Read a string from the keyboardpublic static String readString(){BufferedReader br= new BufferedReader(new InputStreamReader(System.in), 1);// Declare and initialize the stringString string = "";// Get the string from the keyboardtry{string = br.readLine();}catch (IOException ex){System.out.println(ex);}// Return the string obtained from the keyboardreturn string;}// Read an int value from the keyboardpublic static int readInt(){return Integer.parseInt(readString());}// Read a double value from the keyboardpublic static double readDouble(){return Double.parseDouble(readString());}// Read a byte value from the keyboardpublic static byte readByte(){return Byte.parseByte(readString());}// Read a short value from the keyboardpublic static short readShort(){return Short.parseShort(readString());}// Read a long value from the keyboardpublic static long readLong(){return Long.parseLong(readString());}// Read a float value from the keyboardpublic static float readFloat(){return Float.parseFloat(readString());}}加密算法程序:public class mtoc{//输⼊明⽂和密钥,⽤输⼊的密钥对明⽂进⾏加密public static void main(String[] args){int i;char[] c=new char[100];char[] k1=new char[100];//输⼊System.out.print("enter a mingwen string:");String m=MyInput.readString();System.out.print("enter a key string:");String k=MyInput.readString();//构造密钥对照表for(i=0;i<k.length();i++){if(k.charAt(i)>='a'&&k.charAt(i)<='z')k1[i]=(char)(k.charAt(i)-97);if(k.charAt(i)>='A'&&k.charAt(i)<='Z')k1[i]=(char)(k.charAt(i)-65);}//加密for(i=0;i<m.length();i++){if(m.charAt(i)>='a'&&m.charAt(i)<='z')c[i]=(char)((m.charAt(i)-97+k1[i%k.length()])%26+97);if(m.charAt(i)>='A'&&m.charAt(i)<='Z')c[i]=(char)((m.charAt(i)-65+k1[i%k.length()])%26+65);}//输出密⽂for(i=0;i<c.length;i++)System.out.print(c[i]);}}解密算法程序:public class ctom{//输⼊密⽂和密钥,⽤密钥对密⽂解密public static void main(String[] args){int i;char[] m=new char[100];char[] k1=new char[100];//输⼊System.out.print("enter the miwen string:");String c=MyInput.readString();System.out.print("enter the key string:");String k=MyInput.readString();//构造密钥对照表for(i=0;i<k.length();i++){if(k.charAt(i)>='a'&&k.charAt(i)<='z')k1[i]=(char)(k.charAt(i)-97);if(k.charAt(i)>='A'&&k.charAt(i)<='Z')k1[i]=(char)(k.charAt(i)-65);}//解密for(i=0;i<c.length();i++){if(c.charAt(i)>='a'&&c.charAt(i)<='z')m[i]=(char)((c.charAt(i)-97-k1[i%k.length()]+26)%26+97);if(c.charAt(i)>='A'&&c.charAt(i)<='Z')m[i]=(char)((c.charAt(i)-65-k1[i%k.length()]+26)%26+65);}//输出明⽂for(i=0;i<m.length;i++)System.out.print(m[i]);}}需要⽤到的MyInput.java类:// MyInput.java: Contain the methods for reading int, double, and // string values from the keyboardimport java.io.*;public class MyInput{// Read a string from the keyboardpublic static String readString(){BufferedReader br= new BufferedReader(new InputStreamReader(System.in), 1);// Declare and initialize the stringString string = "";// Get the string from the keyboardtry{string = br.readLine();}catch (IOException ex){System.out.println(ex);}// Return the string obtained from the keyboardreturn string;}// Read an int value from the keyboardpublic static int readInt(){return Integer.parseInt(readString());}// Read a double value from the keyboardpublic static double readDouble(){return Double.parseDouble(readString()); }// Read a byte value from the keyboard public static byte readByte(){return Byte.parseByte(readString());}// Read a short value from the keyboard public static short readShort(){return Short.parseShort(readString());}// Read a long value from the keyboard public static long readLong(){return Long.parseLong(readString());}// Read a float value from the keyboard public static float readFloat(){return Float.parseFloat(readString());}}。
四种加密解密算法的源代码:移位密码、仿射密码、维吉尼亚密码以及置换密码#include <stdio.h>#include <conio.h>#include <string.h>#include <malloc.h>void Shift() /*移位密码*/{char c[100];int length, i=0, key=0;clrscr();printf("********Shift Cipher********\nPlease input primal sentence: ");gets(c);length = strlen(c);printf("Input the key(0~26): ");scanf("%d", &key);getchar();if(key<0){printf("The value of key is error!\nPress any key to return...");getch();return;}for(i=0; i<length; i++){if(c[i]>96&&c[i]<123)c[i] = (c[i]+key-97)%26+65;else if(c[i]>64&&c[i]<91)c[i] = (c[i]+key-65)%26+65;}printf("Result is: %s\n", c);for(i=0; i<length; i++){if(c[i]>64&&c[i]<91)c[i] = (c[i]-key-65+26)%26+97;}printf("\nAfter translated the sentence,we can see the primal sentence as follow:\n%s\n", c);printf("Press any key to return...");getch();}int 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() /*仿射密码*/{char c[100];int length, i=0, ka=0, kb=0, tmp;clrscr();printf("********Affine Cipher********\nPlease input primal sentence: "); gets(c);length = strlen(c);printf("Input the key(2 numbers): ");scanf("%d%d", &ka, &kb);getchar();if(gcd(ka,26)!=1){printf("The value of the key is error!\nPress any key to return..."); return;}for(i=0; i<length; i++){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("Result is: %s\n", c);for(i=0; i<length; i++){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("\nAfter translated the sentence,we can see the primal sentence as follow:\n%s\n", c);printf("Press any key to return...");getch();}void Vigenere() /*维吉利亚密码*/{char c[100], key[100];int lenc, lenk, i=0, j=0, tmp;clrscr();printf("********Vigenere Cipher********\nPlease input primal sentence: "); gets(c);lenc = strlen(c);strcpy(c, strupr(c));printf("Input the key: ");gets(key);lenk = strlen(key);strcpy(key, strupr(key));for(; i<lenc; i++){j = j%lenk;if(c[i]>64&&c[i]<91){c[i] = (c[i]-65+key[j]-65)%26+65;j++;}}printf("Result is: %s\n", c);for(i=0, j=0; i<lenc; i++)j = j%lenk;if(c[i]>64&&c[i]<91){tmp = c[i]-65-(key[j]-65);if(tmp>=0)c[i] = tmp%26+97;elsec[i] = (tmp+26)%26+97;j++;}}printf("\nAfter translated the sentence,we can see the primal sentence as follow:\n%s\n", c);printf("Press any key to return...");getch();}void Permutation() /*置换密码*/{char c[100], *q;int *key, len, m, i, j=0;clrscr();printf("********Permutation Cipher********\nPlease input primal sentence: "); gets(c);strcpy(c, strupr(c));len = strlen(c);for(i=0; i<len; i++){if(c[i]<65||c[i]>90){for(j=i; j<len-1; j++)c[j] = c[j+1];len--;}}c[len] = '\0';printf("Input the length of the key: ");scanf("%d", &m);key = (int)malloc(m*sizeof(int));q = (int)malloc(len*sizeof(int));printf("Input the key: ");for(i=0; i<m; i++)scanf("%d", key+i);key[i]--;}getchar();for(i=0; i<len; i++){j = (i/m)*m;q[i] = c[*(key+i%m)+j];}q[i] = '\0';printf("Result is: %s\n", q);for(i=0, j=0; i<len; i++){j = (i/m)*m;c[*(key+i%m)+j] = q[i]+32;}c[len] = '\0';printf("After translated the sentence,we can see the primal sentence as follow:\n%s\n", c);printf("Press any key to return...");free(key);free(q);getch();}void main(){char i = '0';clrscr();while(i!='5'){clrscr();printf("********Press 1~5 to choose:********\n");printf("1. Shift Cipher\n2. Affine Cipher\n3. Vigenere Cipher\n4. Permutation Cipher\n5. Exit\n");i = getch();if(i=='1')Shift();else if(i=='2') Affine();else if(i=='3') Vigenere(); else if(i=='4') Permutation(); else if(i=='5') break;}}。
Vigenere破译系统实验报告一、破译算法的基本思想:Vigenere密码的破译总体来说分为五个部分:1、初始化密文:对于给定的一篇密文我们必须首先进行初始化,初始化的主要作用是为了将密文中的一些非字母全部去掉。
2、密钥长度的推算:统计密文中26个字母出现的概率并将其存放在rate[]数组中,根据获得的rate[]数组计算出重合指数IC,然后通过公式length = ((0.0687 - 0.0385) / (IC - 0.0385))推算出密钥的长度。
3、推算出密钥:根据获得的密钥长度计算出密文分成多少行,row=密文长度/密钥长度,如果密文长度%密钥长度小于密钥长度,则将剩下的密文存放在最后一行lastLength,然后将密文分组,通过生成的每组密文,分别求出移位的加密字母,并合成完整的密钥。
4、破译获得明文:前几步已经破译得到了密文的密钥,那么接下来的操作就相当于密钥和密文已知的情况下解密获得明文,所以我们直接通过传入密文和密钥两个参数调用解密函数就可以算出本篇密文对应的明文。
二、实现代码(1)主调用函数实现代码:package vigenere4;import java.io.BufferedReader;import java.io.FileReader;public class Test {static String c=null;public static void main(String[] args) throws Exception {BufferedReader br=new BufferedReader(newFileReader("e:\\miwen.txt"));//密文文本StringBuffer sbuf=new StringBuffer();//缓冲字符串String line=null;while((line=br.readLine())!=null){sbuf.append(line);//追加到缓冲字符串中}br.close();//读取结束String ciphertext=sbuf.toString();//转换成字符串类型String key = "";key= GetKey.cracker(ciphertext);// 调用破解算法求出密钥System.out.println("破译获得的密钥为:"+key);char mingwen[]=(JieMi.jieMi(ciphertext, key)).toCharArray();//转换成数组类型,方便控制密文以多行形式输出System.out.println("破译得到的明文为:");for(int i=1;i<=mingwen.length;i++){System.out.print(mingwen[i-1]);if(i%60==0){ //每60个字母为一行输出System.out.println();}}bw.write(JieMi.jieMi(ciphertext, key));//将破译的明文写入文本bw.flush();bw.close();br.close();}}(2)破译密钥的代码实现package vigenere4public class GetKey {private static final double LETTER_FREQUENCY[] = { 0.0788, 0.0156, 0.0268,0.0389, 0.1268, 0.0256, 0.0187, 0.0573, 0.0707, 0.0010, 0.0060,0.0394, 0.0244, 0.0706, 0.0776, 0.0186, 0.0009, 0.0594, 0.0634,0.0978, 0.0280, 0.0102, 0.0214, 0.0016, 0.0202, 0.0006 };//26个英文字母在正常英文中出现的概率public static String cracker(String ciphertext) {String key = "", // 存放密钥tempCiphertext = "";// 存放将密文分组后的同组密文int keyLength = 0, // 密钥长度row = 0, // 密文所分成的列数,不记最后一行last_length = 0, // 最后一行长度ciphertextLength;// 密文长度ciphertext = initialize(ciphertext);//初始化密文ciphertextLength = ciphertext.length();// 获得密文长度keyLength = getKeyLength(getRate(ciphertext));// 调用获取密钥长度函数row = (int) ciphertextLength / keyLength;// 获取整数位个行last_length = ciphertextLength % keyLength;// 如最后一行个数小于密钥长度,则存放最后一行的密文个数for (int i = 0; i < keyLength; i++) {tempCiphertext = "";for (int j = 0; j < row; j++) {// 把密文分组tempCiphertext += ciphertext.charAt(keyLength * j + i);// 从整数组当中抽取同组密文}if (last_length > i) {tempCiphertext += ciphertext.charAt(keyLength * row + i);// 从最后余下的密文中抽取同组密文}key += getValue(getRate(tempCiphertext));// 通过生成的每组密文,分别求出移位的加密字母,并合成完整的密钥}return key;}//初始化函数private static String initialize(String ciphertext) {String initialized = "";ciphertext = ciphertext.toLowerCase();//将大写字母转化为小写字母for (int i = 0; i < ciphertext.length(); i++) {char temp = ciphertext.charAt(i);if (temp >= 'a' && temp <= 'z')//将密文中的非字母全部除去initialized += temp;}return initialized;}//获取本段密文中26个字母出现的概率private static double[] getRate(String text) {double[] rate = new double[26];int length = 0;for (int i = 0; i < text.length(); i++) {char temp = text.charAt(i);if (temp >= 'a' && temp <= 'z') {//去除小写字母外的一切字母rate[temp - 97]++;length++;}}for (int i = 0; i < 26; i++) {rate[i] /= length;}return rate;}//破解密钥的长度private static int getKeyLength(double[] rate) {double length = 0.0, IC = 0.0;for (int i = 0; i < rate.length; i++) {IC += (rate[i] * rate[i]);// 计算出重合指数}length = ((0.0687 - 0.0385) / (IC - 0.0385));// 通过公式得出密钥的长度//对密钥长度四舍五入if (length % (int) length < 0.5)return (int) length;elsereturn (int) (length + 1);}//求出每一个密文对应的明文字符private static char getValue(double[] rate) {int Offset = 0;//位移个数double sum = 0.0, d = 0.0, min = 1.0;// 记录与0.065差值最小的数for (int i = 0; i < 26; i++) {for (int j = i; j < i + 26; j++) {sum += rate[j % 26] * LETTER_FREQUENCY[j - i];//移位计算出重合指数}//获取最接近0.065的值d = Math.abs(sum - 0.065);if (d < min) {min = d;Offset = i;}sum = 0;}return (char) (Offset + 97);//返回解出的加密字符}}(3)密钥已知时解密算法的代码实现package vigenere4;public class JieMi {String c=null;public static String jieMi(String ciphertext,String key)throws Exception{//解密算法String plaintext = "";char tempCiphertext, tempKey;key= key.toLowerCase();//把密钥转成小写for (int i = 0, j = 0; i < ciphertext.length(); i++, j++) {tempCiphertext = ciphertext.charAt(i);// 截取密文中的单个字符tempKey=key.charAt(j);// 截取密钥中的单个字符if (tempCiphertext >= 'a' && tempCiphertext <= 'z') {// 密文为小写字母处理情况plaintext += (char) ((tempCiphertext - 97 - tempKey + 97 + 26) % 26 + 97);} else if (tempCiphertext >= 'A' && tempCiphertext <= 'Z') {// 密文为大写字母处理情况plaintext += (char) ((tempCiphertext - 65 - tempKey + 97 + 26) % 26 + 65);} else// 原文为其他字符时不改变plaintext += tempCiphertext;if (j >= key.length() - 1)j = -1;// 如果密钥结束,重复从密钥第一位继续加密}return plaintext;}}三、测试数据集:在本系统中破译的密文我设计的是从文本读入的,在本测试中文本存放在E 盘下,路径为"e:\\miwen.txt"。
维吉利亚密码维吉利亚(Vigenere)密码Vigenere是法国的密码学专家,Vigenere密码是以他的名字命名的。
该密码体制有一个参数n,在加密解密时,把英文字母用数字代替进行运算,并按n个字母一组进行变换。
明文空间、密文空间及密钥空间都是长度为n 的英文字母串的集合,因此可表示为P=C=K=(Z26)n。
加密变换如下: 设密钥k=(k1,k2,…,k n),明文P=(m1,m2,…,m n),加密函数为e k(P)=(c1,c2,…,c n), 其中c i=(m i+k i) (mod 26),i=1,2,…,n。
对密文c=(c1,c2,…,c n),密钥k=(k1,k2,…,k n),解密变换为d k(c)=(m1,m2,…,m n),其中m i=(c i-k i) (mod 26),i=1,2,…,n。
【例题】:设n=6,密钥是cipher,这相应于密钥k=(2,8,15,7,4,17),明文是“this cryptosystem is not secure”,试用Vigenere密码对其加密。
解:首先将明文按每6个分为一组,然后与密钥进行模26相加得t h i s c r19 7 8 18 2 172 8 15 7 4 1721 15 23 25 6 8V P X Z G Iy p t o s y24 15 19 14 18 242 8 15 7 4 170 23 8 21 22 15A X I V W Ps t e m i s18 19 4 12 8 182 8 15 7 4 1720 1 19 19 12 9U B T T M Jn o t s e c13 14 19 18 4 22 8 15 7 4 1715 22 8 25 8 19P W I Z I Tu r e20 17 42 8 1522 25 19W Z T相应的密文是“VPXZGI AXIVWP UBTTMJ PWIZIT WZT”。
vigenere加密算法例题以下是一个Vigenere 加密算法的例题,假设要加密的消息为"Hello, World!",密钥为"QWER":```$ cat message.txtHello, World!$ cat key.txtQWER$ python encrypt.pyKXJYTUVKGIUFNYA$ cat encrypted.txtKXJYTUVKGIUFNYA$```加密过程如下:1. 将密钥和消息分别读入内存,并将它们按照字母顺序排序,以便后续处理。
2. 创建一个长度为密钥长度的随机数组,用于存储加密后的结果。
3. 遍历密钥和消息中的每个字符,如果是字母,则将其与加密表中对应的字母进行异或运算。
4. 如果加密后的结果是一个字母,则将其与加密表中对应的字母进行异或运算。
5. 如果加密后的结果是一个数字,则将其转换为对应的字母,并将其与加密表中对应的字母进行异或运算。
6. 将加密后的结果写入输出文件。
下面是一个Python 的实现代码:```pythonimport randomdef vigenere_encrypt(message, key):# 将密钥和消息按照字母顺序排序sorted_message = ''.join(sorted(message))sorted_key = ''.join(sorted(key))# 创建一个长度为密钥长度的随机数组cipher_table = [chr(65 + random.randint(0, 25)) for i in range(len(sorted_key))]# 加密消息encrypted_message = []for char in sorted_message:if char.isalpha():encrypted_char = chr((ord(char) ^ ord(cipher_table[len(sorted_key) - i - 1])) & 0xff)encrypted_message.append(encrypted_char)elif char.isdigit():encrypted_char = chr((ord(char) - 48) % 26 + 65)encrypted_message.append(encrypted_char)else:encrypted_message.append(char)# 将加密后的结果写入输出文件with open('encrypted.txt', 'w') as f:f.write(''.join(encrypted_message))vigenere_encrypt('Hello, World!', 'QWER')```在上述代码中,我们首先将密钥和消息按照字母顺序排序,然后创建一个长度为密钥长度的随机数组,用于存储加密后的结果。
1.凯撒密码的加解密源代码:#include<stdafx.h>#include <stdio.h>#include <string.h>int main(){char s[100],c;int i,p,d,e;printf("请选择: A.加密B.解密Q.退出\n"); scanf("%c",&c);if(c=='a'||c=='A'){printf("输入明文:");scanf("%s",&s);p=strlen(s);printf("请设置偏移量:");scanf("%d",&d);for(i=0;i<p;i++){if(s[i]>='a' && s[i]<='z')s[i]=(s[i]-'a'+d)%26+'a';else if(s[i]>='A' && s[i]<='Z')s[i]=(s[i]-'A'+d)%26+'A';else s[i]=s[i]+d;}printf("%s",s);printf("\n\n\n");}if(c=='b'||c=='B'){printf("请输入密文:");scanf("%s",&s);p=strlen(s);printf("请输入加密的偏移变量:");scanf("%d",&d);for(i=0;i<p;i++){if(s[i]>='a' && s[i]<='z'){e=s[i]-'a'-d;if(e<=0)s[i]=(e+26)%26+'a';else s[i]=e%26+'a';}else if(s[i]>='A' && s[i]<='Z'){e=s[i]-'A'-d;if(e<0)s[i]=(e+26)%26+'A';else s[i]=e%26+'A';}else s[i]=s[i]-d;}printf("%s",s);printf("\n\n");}if(c=='q'||c=='Q')return 0;return 0;}运行结果是:2.维吉尼亚密码的加解密源代码:#include "stdafx.h"#include<iostream>using namespace std;#define MINCHAR 32#define CHARSUM 94char table[CHARSUM][CHARSUM];bool Init();bool Encode(char* key, char* source, char* dest);bool Dncode(char* key, char* source, char* dest);int main(){if(!Init()){cout << "初始化错误!" << endl;return 1;}char key[256];char str1[256];char str2[256];int operation;while(1){do{cout << "请选择一个操作:1. 加密;2. 解密;-1. 退出\n"; cin >> operation;}while(operation != -1 && operation != 1 && operation != 2);if(operation == -1)return 0;else if(operation == 1)//加密{cout << "请输入密钥:";cin >> key;cout << "请输入待加密字符串:";cin >> str1;Encode(key, str1, str2);cout << "加密后的字符串:" << str2 << endl;}else if(operation == 2)//解密{cout << "请输入密钥:";cin >> key;cout << "请输入待解密字符串:";cin >> str1;Dncode(key, str1, str2);cout << "解密后的字符串:" << str2 << endl;}cout << endl;}return 0;}// 初始化维吉尼亚方阵bool Init(){int i, j;for(i = 0; i < CHARSUM; i++){for(j = 0; j < CHARSUM; j++){table[i][j] = MINCHAR + (i + j) % CHARSUM;}}return true;}// 加密// key:密钥// source:待加密的字符串// dest:经过加密后的字符串bool Encode(char* key, char* source, char* dest){char* tempSource = source;char* tempKey = key;char* tempDest = dest;do{*tempDest = table[(*tempKey) - MINCHAR][(*tempSource) - MINCHAR]; tempDest++;if(!(*(++tempKey)))tempKey = key;}while(*tempSource++);dest[strlen(source)] = 0;return true;}// 解密// key:密钥// source:待解密的字符串// dest:经过解密后的字符串bool Dncode(char* key, char* source, char* dest){char* tempSource = source;char* tempKey = key;char* tempDest = dest;char offset;do{offset = (*tempSource) - (*tempKey);offset = offset >= 0 ? offset : offset + CHARSUM; *tempDest = MINCHAR + offset;tempDest++;if(!(*(++tempKey)))tempKey = key;}while(*++tempSource);dest[strlen(source)] = 0;return true;}运行结果如下:。
2.1维吉尼亚密码
先用一个例子来说明维吉尼亚密码(以下简称维密)的加密过程:
用一个单词或一段英文作为密钥,在这里我们选取单词back。
如果要加密的明文是hello world,将每一位明文与密钥对应:
明文:h e l l o w o r l d
密钥:b a c k b a c k b a
可以看出当密钥的长度短于明文时,要将密钥重复使用。
每一位的加密过程与凯撒密码类似,我们将a~z的值定为0~25,加密就是将每一位明文值与密钥值相加。
例如h的值是7,b 的值是1,相加后得到8,所以密文的第一个字母是i。
以此类推,可以得到最后的密文为ienvp wqbmd。
加密过程可以写成一个式子:ci = (pi + ki) mod 26
是不是看上去跟广义的凯撒密码很像?ci表示第i位密文字母,pi表示第i位明文字母,ki 表示第i位密钥字母。
维密与凯撒密码的区别在于明文改变的值不是固定的,例如上例中第一个字母h增大了1位,第二个字母保持不变,第三个字母l增大了2位。
我们使用维密的时候,可以用计算机加密得到密文,也可以对较短的明文使用查表法。