原理

     Vigenere 密码在加密/解密时,把英文字母映射为 0-25 的数字再进行计算,并按 n 个 字母一组进行变换。明文空间、密钥空间及密文空间都是长度为 n 的英文字母串的集合。


设密钥 k=(k1,k2,···, kn),明文 m=(m1,m2,···, mn),则加密算法为 

Ek(m)=(c1,c2,···, cn)

其中,ci=(mi+ki)( mod 26), i=1,2,···, n。

对密文 c=(c1,c2,···, cn),解密算法为

Dk(c)=(m1,m2,···, mn)

其中,mi=(ci-ki)( mod 26), i=1,2,···, n。 2


核心函数 

下面是主要的核心加解密函数:

/*--- 函数名称:encrypt()。 函数功能:对单个的明文字母进行加密,得到密文字母。————*/
Char encrypt(char ch1,char ch2){
if(ch1>=‘A’&& ch1<=‘Z’ && ch2>=‘A’ &&ch2<=‘Z’) //大写字母
return ‘A’+(ch1 - ‘A’+ch2-‘A’)%26;
if(ch1>=‘a’&& ch1<=‘z’ && ch2>=‘a’ &&ch2<=‘z’) //小写字母
return ‘a’+(ch1 - ‘a’+ch2-‘a’)%26;
return ch1; }


/*---- 函数名称:decrypt()。 函数功能:对单个的密文字母进行解密,还原成明文字母――*/
Char decrypt (char ch1,char ch2){
if(ch1>=‘A’&& ch1<=‘Z’ && ch2>=‘A’ &&ch2<=‘Z’)
return ‘A’+(ch1 - ‘A’+26-(ch2-‘A’ ))%26;
if(ch1>=‘a’&& ch1<=‘z’ && ch2>=‘a’ &&ch2<=‘z’)
return ‘a’+(ch1 - ‘a’+26-(ch2-‘a’) )%26;
return ch1; }

源代码

1.下面给出整个加密的完整程序:

#include<iostream>                   //这是加密的完整代码
#include<string.h> //解密只需要修改主要的函数和导入文件名即可
#include<fstream>
using namespace std;
#define max 1000


int get_lens(char ch[]) //获取明文的字符长度
{
//return sizeof(ch[])/sizeof(ch[0]);
return strlen(ch);

}

char get_file(char buffer[max],char filename[]){ //将明文读取到数组

//ifstream in("%s",filename,"r");
ifstream in("test.txt");
if (! in.is_open())
{ cout << "Error opening file"; exit (1); }
while (!in.eof() )
{
in.getline (buffer,max*10);
// cout << buffer << endl;
}
return 0;
}
//加密的核心算法
char encrypt_(char ch1,char ch2){
if(ch1>'A'&&ch1<'Z'&&ch2>'A'&&ch2<'Z') //大写
return 'A'+(ch1-'A'+ch2-'A')%26;
if(ch1>'a'&&ch1<'z'&&ch2>'a'&&ch2<'z') //小写
return 'a'+(ch1-'a'+ch2-'a')%26;
return ch1; //其他符号不加密直接返回

}




int main(){
int lens,keylen,i,j=0; //j为密钥元素位置
char encrypt[max],key[max],code[max];
char name[max];
cin>>key; //输入key
//encrypt = open(filename,ios::in);
cout<<"enter filename:";
cin>>name;
get_file(encrypt,name);
lens=get_lens(encrypt); //获取密文长度
keylen=get_lens(key); //计算秘钥长度
cout<<"file_len:"<<lens<<"\n"<<"key_len:"<<keylen<<endl;
for(i=0;i<=lens-1;i++) {
if(j>=keylen-1) j=0;
code[i]=encrypt_(encrypt[i],key[j]);
j++;
}
cout<<"trans:len:::"<<i<<endl;
if(i=lens-1)
{
ofstream code_("code.txt");
if(code_.is_open()){

for(i=0;i<=lens-1;i++)
{ code_ << code[i]; }
code_.close();
}
cout<<"Encrypt successful!"<<endl;
}

else
cout<<"Encrypt failure!"<<endl;

return 0;
}

2.下面是解密的完整代码实现:(在上面直接改的)

#include<iostream>
#include<string.h>
#include<fstream>
using namespace std;
#define max 1000


int get_lens(char ch[])
{
//return sizeof(ch[])/sizeof(ch[0]);
return strlen(ch);

}

char get_file(char buffer[max],string filename){

ifstream in("code.txt");
if (! in.is_open())
{ cout << "Error opening file"; exit (1); }
while (!in.eof() )
{
in.getline (buffer,max*10);
// cout << buffer << endl;
}
return 0;
}
char encrypt_(char ch1,char ch2){
if(ch1>'A'&&ch1<'Z'&&ch2>'A'&&ch2<'Z') //大写
return 'A'+(ch1-'A'+26-ch2+'A')%26;
if(ch1>'a'&&ch1<'z'&&ch2>'a'&&ch2<'z') //小写
return 'a'+(ch1-'a'+26-ch2+'a')%26;
return ch1; //其他符号不加密直接返回

}




int main(){
int lens,keylen,i,j=0; //j为密钥元素位置
char encrypt[max],key[max],code[max];
//string encrypt,key,code;
string name;
cin>>key; //输入key
//encrypt = open(filename,ios::in);
cout<<"enter filename:";
cin>>name;
get_file(encrypt,name);
lens=get_lens(encrypt); //获取密文长度
keylen=get_lens(key);
cout<<"file_len:"<<lens<<"\n"<<"key_len:"<<keylen<<endl;
for(i=0;i<=lens-1;i++) {
if(j>=keylen-1) j=0;
code[i]=encrypt_(encrypt[i],key[j]);
j++;
}
cout<<"trans:len:::"<<i<<endl;
if(i=lens-1)
{
ofstream code_("txt.txt");
if(code_.is_open()){

for(i=0;i<=lens-1;i++)
{ code_ << code[i]; }
code_.close();
}
cout<<"Dencrypt successful!"<<endl;
}

else
cout<<"Dencrypt failure!"<<endl;

return 0;
}


附:Vigener的唯密文破解,需要使用到大量的概率论原理,且在明文长度越长的情况下 ,破解成功的概率越高,具有不确定性,后面会单独给出一篇文章。


加油~加油!