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.測試結果:
筆記拂曉攻擊的行動通知。
參考: