原理介绍
在凯撒密码中,每一个字母通过一定的偏移量(即密钥K)变成另外一个字母,而维吉尼亚密码就是由多个偏移量不同的凯撒密码组成,属于多表密码的一种。在一段时间里它曾被称为“不可破译的密码”。.
维吉尼亚密码在加密和解密时,需要一个表格进行对照。表格一般为26*26的矩阵,行和列都是由26个英文字母组成。加密时,明文字母作为列,密钥字母作为行,所对应坐标上的字母即为对应的密文字母。
可以用上述表格直接查找对应的密文,也可通过取模计算的方式。用0-25代替字母A-Z,C表示密文,P表示明文,K表示密钥,维吉尼亚加密算法可表示为:
密文可表示为:
举例说明,假设明文为“I AM A CHINESE”,密钥为“CHINA”,那么密文就是“L HU N CJPVRSG”。具体过程如下表:
3.2 C#代码
// Vigenere Cipher(维吉尼亚密码)
public sealed class Vigenere
{
// 加密
public static string VigenereEncrypt(string plaintext, string key)
{
string ciphertext = "";
byte[] origin = Encoding.ASCII.GetBytes(plaintext.ToUpper());
byte[] keys = Encoding.ASCII.GetBytes(key.ToUpper());
int length = origin.Length;
int d = keys.Length;
for (int i = 0; i < length; i++)
{
int asciiCode = (int)origin[i];
// 加密(移位)
asciiCode = asciiCode + (int)keys[i % d] - (int)'A';
if (asciiCode > (int)'Z')
{
asciiCode -= 26;
}
byte[] byteArray = new byte[] { (byte)asciiCode };
// 将偏移后的数据转为字符
ASCIIEncoding asciiEncoding = new ASCIIEncoding();
string strCharacter = asciiEncoding.GetString(byteArray);
ciphertext += strCharacter;
}
return ciphertext;
}
// 解密
public static string VigenereDecrypt(string ciphertext, string key)
{
string plaintext = "";
byte[] origin = Encoding.ASCII.GetBytes(ciphertext.ToUpper());
byte[] keys = Encoding.ASCII.GetBytes(key.ToUpper());
int length = origin.Length;
int d = keys.Length;
for (int i = 0; i < length; i++)
{
int asciiCode = (int)origin[i];
// 解密(移位)
asciiCode = asciiCode - (int)keys[i % d] + (int)'A';
if (asciiCode < (int)'A')
{
asciiCode += 26;
}
byte[] byteArray = new byte[] { (byte)asciiCode };
// 将偏移后的数据转为字符
ASCIIEncoding asciiEncoding = new ASCIIEncoding();
string strCharacter = asciiEncoding.GetString(byteArray);
plaintext += strCharacter;
}
return plaintext;
}
}