原理介绍
	在上述加密方法中,密文字母和明文字母之间是一对一映射 ,其加密方法均无法掩盖明文数据的统计特性,通过统计计算密文字母的统计特性,比较容易找出明文和密文之间的对应关系,从而达到破解密文的目的。
以英文文章为例,不同的字母在文章中出现的频率是不同的,美国密码学家William Freidman在对大量英文文章进行统计后,得到不同英文字母的普遍使用频率,不同英文字母(不区分大小写)的使用频率见下表。| 字母 | 频率 | 字母 | 频率 | 字母 | 频率 | 
| A | 0.0856 | J | 0.0133 | S | 0.0607 | 
| B | 0.0139 | K | 0.0042 | T | 0.1045 | 
| C | 0.0279 | L | 0.0339 | U | 0.0249 | 
| D | 0.0378 | M | 0.0249 | V | 0.0092 | 
| E | 0.1304 | N | 0.0707 | W | 0.0149 | 
| F | 0.0289 | O | 0.0797 | X | 0.0017 | 
| G | 0.0199 | P | 0.0199 | Y | 0.0199 | 
| H | 0.0528 | Q | 0.0012 | Z | 0.0008 | 
| I | 0.0627 | R | 0.0677 | 
					 | 
				
					 | 
			
以同样的方式还可以统计双字母和三字母的统计特性,例如:在双字母中TH、HE、ER和AN等是使用频率相对较高的双字母组合,而在三字母中则THE、ING、AND和HER等属于使用频率较高的三字母组合。利用双字母和三字母的统计特性,可以更有效地提高简单密码算法的准确性。
对单表代替密码进行改进,产生多表代替密码,多表代替密码隐藏了明文的统计特性,明文的结构信息被隐蔽了。
多表代替密码有两个共同的特征,其一是采用相关单表代换规则,其二是密钥决定代换的具体方法。
	在这类密码算法中,比较典型的多表代替密码是维吉尼亚(Vigenere)密码和希尔(Hill)密码,希尔密码实际上也是多表代替密码的另一种变体。
	
		
	
维吉尼亚密码是多表代替密码中最简单的一种,它的代换规则和凯撒密码类似,每个代换表是明文字母移位到0到25次以后得到的代换单表,其代换表如下表所示。
| 
					 | 
				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 | 
| a | 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 | 
| b | 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 | A | 
| c | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z | A | B | 
| d | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z | A | B | C | 
| e | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z | A | B | C | D | 
| f | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z | A | B | C | D | E | 
| g | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z | A | B | C | D | E | F | 
| h | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z | A | B | C | D | E | F | G | 
| i | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z | A | B | C | D | E | F | G | H | 
| j | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z | A | B | C | D | E | F | G | H | I | 
| k | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z | A | B | C | D | E | F | G | H | I | J | 
| l | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z | A | B | C | D | E | F | G | H | I | J | K | 
| m | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z | A | B | C | D | E | F | G | H | I | J | K | L | 
| n | N | O | P | Q | R | S | T | U | V | W | X | Y | Z | A | B | C | D | E | F | G | H | I | J | K | L | M | 
| o | O | P | Q | R | S | T | U | V | W | X | Y | Z | A | B | C | D | E | F | G | H | I | J | K | L | M | N | 
| p | P | Q | R | S | T | U | V | W | X | Y | Z | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | 
| q | Q | R | S | T | U | V | W | X | Y | Z | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | 
| r | R | S | T | U | V | W | X | Y | Z | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | 
| s | S | T | U | V | W | X | Y | Z | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | 
| t | T | U | V | W | X | Y | Z | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | 
| u | U | V | W | X | Y | Z | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | 
| v | V | W | X | Y | Z | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | 
| w | W | X | Y | Z | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | 
| x | X | Y | Z | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | 
| y | Y | 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 | 
| 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 | 
现设密钥为cipher,明文为seeyoulate,其加密结果如下:
- 密钥:ciphereiph
 - 明文:seeyoulate
 - 
			密文:UMTFSLNIIL
 
		明文的第1个字母为s,密钥的第1个字母为c,密文则是第c行第s列对应的字母U,在明文中第二个字母和第三个字母都是e,但由于密钥不同,因此加密得到的密文也不同,这样,密文隐藏了明文的统计特性。由于密钥的长度为6,那么在第6个字母之后密钥循环使用,即第7个明文字母加密时使用的是密钥的第1个字母,以此类推。因此,与单表代替密码相比维吉尼亚密码具有更高的安全性。
		
Cpp源代码
			完整的实现共包括三个相应的文件,vigenere.h、 vigenere.cpp和main.cpp,在vigenere.h中主要完成对类的声明,vigenere.cpp文件主要完成vigenere.h中声明函数的定义,main.cpp中主要是对象的调用。
			
				 
			
			
			

		
	
				vigenere.h的代码如下: 
			
			#ifndef VIGENERE_H
#define VIGENERE_H
#include<string>
using namespace std;
class Vigenere{
	private:
		int cipherTable[26][26];		//数字编码表 
		string key;				//密钥 
		string explicitly;	        	//待处理的明文 
		string cipherText;			//加密后的密文 
		string explicitlyText;			//解密后的明文 
    public:
    	Vigenere();
		void init();				//初始化 cipherTable 
		void setKey(string k);		//设置加密密钥 
		void setExplicitly(string ex);	//设置明文 
		void encryption();			//加密明文,获得密文 
		void decryption();			//将密文转换为明文 
		void outPutCipherText();		//将处理结果(加密的密文)输出 
		void outPutExplicitlyText();	        //将处理结果(解密的明文)输出  
		int getPosition(int P,int n);	//获取密文解密的位置
};
#endif
vigenere.cpp的代码如下:
			#include "vigenere.h"
#include <iostream>
Vigenere::Vigenere(){
	init();
}
void Vigenere::init(){
	int i,j;
	for(int i=0; i<26; i++){
		for(int j=0; j<26; j++){
			cipherTable[i][j]=(i+j)%26;
		}
	}
}
void Vigenere::encryption(){
	cipherText = explicitly; //初始化密文为明文
	unsigned int i;
	int m,n;
	for(i=0; i<explicitly.length(); i++){
		m=int(explicitly[i]-'a');
		n=int(key[i%(key.length())]-'a');
		cipherText[i]=char('A'+cipherTable[n][m]);
	} 
}
void Vigenere::decryption(){
	explicitlyText=cipherText;	//初始化解密明文为密文 
	unsigned int i;
	int m,n;
	for(i=0;i<cipherText.length();i++){
		n=int(key[i%(key.length())]-'a');
		m=getPosition(i,n);
		explicitlyText[i]=char('a'+m);
	} 
}
int Vigenere::getPosition(int p, int n){
	int position;
	int i;
	for(i=0;i<26;i++){
		if(char(cipherText[p])==char('A'+cipherTable[n][i])){
			position=i;
			break;
		}
	}
	return position;
}
void Vigenere::setKey(string k){
	key=k;
}
void Vigenere::setExplicitly(string ex){
	explicitly=ex;
}
void Vigenere::outPutCipherText(){
	cout<<cipherText<<endl;
}
void Vigenere::outPutExplicitlyText(){
	cout<<explicitlyText<<endl;
}
main.cpp的代码如下: 
			#include <iostream>
#include <string>
#include "vigenere.h"
/* run this program using the console pauser or add your own getch, system("pause") or input loop */
int main(int argc, char** argv) {
	
	Vigenere *v = new Vigenere();
	string key = "cipherciph";
	string ex = "seeyoulate";
	v->setKey(key);
	v->setExplicitly(ex);
	v->encryption();
	cout<<"加密效果:";
	v->outPutCipherText();
	
	v->decryption();
	cout<<"解密效果:";
	v->outPutExplicitlyText();
	
	return 0;
}
执行效果如下:
京公网安备 11010502036488号