[.NET][C#]密碼學(Virginia cipher)

Virginia cipher維吉尼亞密碼,中世紀後期多表替換式加密,由16世紀義大利密碼學家Bellaso所創,後誤植為19世紀法國外交官維吉尼亞,維吉尼亞密碼以其簡單易用而著稱,同時初學者通常難以破解,因而又被稱為不可破譯的密碼。

凱撒加密法中,明文的每一個字母加密都有相同的偏移量,維吉尼亞密碼則是每個明文字母都給予不同的偏移量,這個偏移量來自事前輸入的基碼,因此通常需要搭配一個表格來快速對應的加密後的字母位置。

維吉尼亞表格:

貝拉索當時的密碼表

 

  • 假設明文: ATTACKATDAWN (拂曉攻擊)
  • 基碼關鍵詞:LEMON

1.首先我們需要一段計算關鍵詞偏移量的方法:

//取得基碼偏移量
public List<int> getEncryptionKey(string Key)
{
    List<int> ListOffset = new List<int>();
    foreach (char c in Key.ToUpper())
    {
        ListOffset.Add(c - 'A');
    }
    return ListOffset;
}

//取得解密基碼偏移量
public List<int> getDecryptionKey(string Key)
{
    List<int> ListOffset = new List<int>();
    foreach (char c in Key.ToUpper())
    {
        ListOffset.Add(26 - (c - 'A'));
    }
    return ListOffset;
}

2.維吉尼亞多表替換演算: 當基碼字數小於明文字數時,重複循環基碼,以此類推。

public string VirginiaAlgorithm(string PlainText, List<int> ListOffset)
{

    //需要置換的拉丁字母
    char[] Encyclopedia = "ABCDEFGHIJKLMNOPQRSTUVWXYZ".ToCharArray();
    StringBuilder sb = new StringBuilder();
    int keyIdx = 0;
    foreach (char c in PlainText.ToUpper())
    {
        int idx = c - 'A';
        if (idx >= 0 && idx < Encyclopedia.Length)
        {
            sb.Append(Encyclopedia[((idx + ListOffset[keyIdx]) % 26)]);
        }
        else
        {
            sb.Append(c);
        }
        //下一個偏移量
        keyIdx++;
        //偏移量循環
        if (keyIdx == ListOffset.Count)
        {
            keyIdx = 0;
        }
    }
    return sb.ToString();
}

3.測試程式

//輸入拉丁字母
string PlainText = "ATTACKATDAWN";
//維吉尼亞加密:
string CipherText = VirginiaAlgorithm(PlainText, getEncryptionKey("LEMON"));
Console.WriteLine("輸入:{0}", PlainText);
Console.WriteLine("加密:{0}", CipherText);

//解密
string PlainText2 = VirginiaAlgorithm(CipherText, getDecryptionKey("LEMON"));
Console.WriteLine("解密:{0}", PlainText2);

4.測試結果:

筆記拂曉攻擊的行動通知。

 

參考:

Giovan Battista Bellaso wiki

維吉尼亞密碼