[加密]C#实现维吉尼亚加密与解密(解密前提为已知密匙)
·
维吉尼亚密码 C# 实现与解析
维吉尼亚密码(Vigenère cipher)是一种经典的多表替换加密算法,通过使用密钥和维吉尼亚方阵(Vigenère square)对明文进行加密和解密。本文将详细介绍维吉尼亚密码的原理,并提供一个完整的 C# Windows Forms 实现。
1. 维吉尼亚密码原理
维吉尼亚密码基于凯撒密码,但使用一个密钥来动态选择加密表。其核心是维吉尼亚方阵,这是一个 26×26 的字母表矩阵:
- 第一行为 A-Z(明文行)
- 第一列为 A-Z(密钥行)
- 每个单元格的字母由“明文列字母”与“密钥行字母”相加(模26)得到
加密时,将明文和密钥转换为数字(A=0, B=1, ..., Z=25),然后通过维吉尼亚方阵查找对应的密文字母。解密则是反向查找过程。
2. C# 实现代码
以下是一个完整的 Windows Forms 应用程序,实现了维吉尼亚密码的加密和解密功能:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
namespace Vigenere
{
public partial class Form1 : Form
{
// 维吉尼亚方阵(26×26)
private string[,] matrix = new string[26, 26];
private ASCIIEncoding ascii = new ASCIIEncoding();
// 密钥、密文、明文
private string key;
private string code;
private string text;
public Form1()
{
InitializeComponent();
#region 生成维吉尼亚方阵
for (int i = 0; i < 26; i++)
{
for (int j = 0; j < 26; j++)
{
int number = 65 + i + j;
if (number > 90)
{
number -= 26;
}
byte[] bt = new byte[] { (byte)number };
matrix[i, j] = ascii.GetString(bt);
}
}
#endregion
}
// 加密按钮点击事件
private void button1_Click(object sender, EventArgs e)
{
key = this.txtKey.Text.ToString().ToUpper();
code = "";
text = this.txtText.Text.ToString().ToUpper();
List<int> keyNum = new List<int>();
// 将密钥转换为数字序列(A=0, B=1, ..., Z=25)
for (int i = 0; i < key.Length; i++)
{
string str = key.Substring(i, 1);
keyNum.Add((int)ascii.GetBytes(str)[0] - 65);
}
int index = -1;
for (int i = 0; i < this.text.Length; i++)
{
// 保留空格
if (this.text.Substring(i, 1).ToString() == " ")
{
code += " ";
continue;
}
index++;
// 加密:matrix[密钥数字, 明文字母数字]
code += matrix[keyNum[index % key.Length],
(int)ascii.GetBytes(this.text.Substring(i, 1))[0] - 65];
}
this.txtCode.Text = code.ToString();
}
// 解密按钮点击事件
private void button2_Click(object sender, EventArgs e)
{
key = this.txtKey.Text.ToString().ToUpper();
code = this.txtCode.Text.ToString().ToUpper();
text = "";
List<int> keyNum = new List<int>();
// 将密钥转换为数字序列
for (int i = 0; i < key.Length; i++)
{
string str = key.Substring(i, 1);
keyNum.Add((int)ascii.GetBytes(str)[0] - 65);
}
int index = -1;
for (int i = 0; i < this.code.Length; i++)
{
// 保留空格
if (this.code.Substring(i, 1).ToString() == " ")
{
text += " ";
continue;
}
index++;
// 解密:在密钥对应的行中查找密文字母
for (int j = 0; j < 26; j++)
{
if (this.code.Substring(i, 1).ToString() == matrix[keyNum[index % key.Length], j])
{
byte[] bt = new byte[] { (byte)(j + 65) };
text += ascii.GetString(bt);
break;
}
}
}
this.txtText.Text = text.ToString();
}
}
}
3. 代码解析
3.1 维吉尼亚方阵生成
在窗体构造函数中,我们生成一个 26×26 的维吉尼亚方阵:
- 外层循环
i表示密钥字母索引(0-25) - 内层循环
j表示明文字母索引(0-25) - 每个单元格的字母 ASCII 码为 65 + i + j(A 的 ASCII 码为 65)
- 如果计算结果超过 90(Z 的 ASCII 码),则减去 26 回到 A-Z 范围
3.2 加密过程
- 将密钥和明文转换为大写
- 将密钥字母转换为数字(A=0, B=1, ..., Z=25)
- 遍历明文字符:
- 如果是空格,直接保留
- 否则,使用公式
matrix[密钥数字, 明文字母数字]查找密文字母 - 密钥循环使用(
index % key.Length)
3.3 解密过程
- 将密钥和密文转换为大写
- 将密钥字母转换为数字
- 遍历密文字符:
- 如果是空格,直接保留
- 否则,在密钥对应的行中查找密文字母的位置
- 找到后,将列索引转换为明文字母
4. 使用示例
假设:
- 密钥:KEY
- 明文:HELLO WORLD
加密过程:
- 密钥 KEY 转换为数字:K=10, E=4, Y=24
- 明文 HELLO WORLD 转换为数字:H=7, E=4, L=11, L=11, O=14, W=22, O=14, R=17, L=11, D=3
- 加密计算:
- H(7) + K(10) = R(17)
- E(4) + E(4) = I(8)
- L(11) + Y(24) = J(9)(35-26=9)
- ...以此类推
- 得到密文:RIJVS GYJVN
5. 程序界面说明
程序包含以下控件:
- txtKey:密钥输入框
- txtText:明文输入框
- txtCode:密文显示框
- button1:加密按钮
- button2:解密按钮
6. 扩展与优化建议
- 支持小写字母:当前实现只处理大写字母,可扩展支持小写
- 支持更多字符:可扩展支持数字、标点符号等
- 性能优化:解密时的查找操作可优化为直接计算
- 错误处理:添加输入验证和异常处理
- 文件加密:扩展为文件加密/解密功能
7. 参考资料
对于维吉尼亚方阵及运用维吉尼亚方阵的加密与解密,可参考维吉尼亚密码_百度百科
程序运行画面结果如下:
(此处可插入程序运行截图)
更多推荐


所有评论(0)