加密算法C#实现:Vigenere密码

 原理介绍

  在凯撒密码中,每一个字母通过一定的偏移量(即密钥K)变成另外一个字母,而维吉尼亚密码就是由多个偏移量不同的凯撒密码组成,属于多表密码的一种。在一段时间里它曾被称为“不可破译的密码”。.

  维吉尼亚密码在加密和解密时,需要一个表格进行对照。表格一般为26*26的矩阵,行和列都是由26个英文字母组成。加密时,明文字母作为列,密钥字母作为行,所对应坐标上的字母即为对应的密文字母。

加密算法C#实现:Vigenere密码

  可以用上述表格直接查找对应的密文,也可通过取模计算的方式。用0-25代替字母A-Z,C表示密文,P表示明文,K表示密钥,维吉尼亚加密算法可表示为:

加密算法C#实现:Vigenere密码

  密文可表示为:

加密算法C#实现:Vigenere密码

  举例说明,假设明文为“I AM A CHINESE”,密钥为“CHINA”,那么密文就是“L HU N CJPVRSG”。具体过程如下表:

加密算法C#实现:Vigenere密码

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;

    }

}