4

首先,我还在学习面向对象编程。好的,我有一个包含不同类型对称算法的组合框。

private void Form3_Load(object sender, EventArgs e)
{
    openencrypt();
    comboBox1.Items.Add("AES");
    comboBox1.Items.Add("DES");
    comboBox1.Items.Add("Rijndael");
    comboBox1.Items.Add("RC2");
    comboBox1.Items.Add("Triple DES");
    comboBox1.SelectedIndex = 0;
}

然后我让我的加密函数检查它们是什么类型。

byte[] hpass;
string nFilepath = Set.nfilepath;
FileStream Open = new FileStream(oFilepath, FileMode.Open, FileAccess.Read);
FileStream Save = new FileStream(nFilepath, FileMode.OpenOrCreate, FileAccess.Write);
SHA512 sh512 = new SHA512Managed();
hpass = sh512.ComputeHash(Encoding.ASCII.GetBytes(textBox1.Text));
PasswordDeriveBytes pdb = new PasswordDeriveBytes(hpass, hash);

if (comboBox1.SelectedIndex.Equals(0))
{
    Aes alg = Aes.Create();
    alg.Key = pdb.GetBytes(32);
    alg.IV = pdb.GetBytes(16);
}
if (comboBox1.SelectedIndex.Equals(1))
{
    DES alg = DES.Create();
    alg.Key = pdb.GetBytes(32);
    alg.IV = pdb.GetBytes(16);
}
if (comboBox1.SelectedIndex.Equals(2))
{
    Rijndael alg = Rijndael.Create();
    alg.Key = pdb.GetBytes(32);
    alg.IV = pdb.GetBytes(16);
}

但是当我不想在每个 if 语句中放置一个加密流时。那么有没有办法将检查卸载到函数并返回对称算法类型?用钥匙和 IV?我完全错了吗?##标题##

4

2 回答 2

2

更面向对象的方法是:

创建要在组合框中显示的算法界面:

public interface IAlgorithmItem
{
    SymmetricAlgorithm CreateAlgorithm();

    string DisplayName { get; }
}

然后,为每个所需的算法创建一个新类:

public class AesAlgorithm : IAlgorithmItem
{
    public AesAlgorithm()
    {
    }

    public SymmetricAlgorithm CreateAlgorithm()
    {
        return Aes.Create();
    }

    public string DisplayName
    {
        get { return "AES"; }
    }
}

public class RijndaelAlgorithm : IAlgorithmItem
{
    public SymmetricAlgorithm CreateAlgorithm()
    {
        return Rijndael.Create(); 
    }

    public string DisplayName
    {
        get { return "Rijndael"; }
    }
}

// ...

然后,您可以创建一个新的项目列表:

var listItems = new List<IAlgorithmItem>() { new AesAlgorithm(), new RijndaelAlgorithm() };

然后你可以将你的组合框绑定到这个列表:

comboBox1.DataSource = listItems;
comboBox1.DisplayMember = "DisplayName";

稍后,您可以引用所选项目:

var algorithmItem = (IAlgorithmItem)comboBox1.SelectedItem;
var algorithm = algorithmItem.CreateAlgorithm();

编辑:更新了 Will 关于使用接口而不是抽象基类的建议。编辑 2:更新为使用创建方法而不是属性,因为操作的结果将在每次访问时创建一个新算法。

于 2012-09-09T08:32:51.540 回答
2

好吧,我的第一个想法是为您提供指向工厂方法抽象工厂模式的 Wikipedia 链接(在那里,我仍然这样做了),但是既然您说您是初学者,我们就不要提前拿出大炮。

基本上,您需要找到所有加密算法的共同特征并创建一个方法,该方法将返回具有该共同特征的对象实例。这种特征的表现可以是 C# 中的抽象类或接口,你很幸运,你选择的所有加密都派生自 SymmetricAlgorithm(“运气”可能是对 System.Security.Cryptography 设计者的侮辱,但我相信他们会为了说明而原谅我;)。

因此,只需通过引入一种新方法来重构您的代码,可能遵循以下思路:

private SymmetricAlgorithm GetAlgorithm(int index)
{
  switch (index)
  {
    case 0:
      return Aes.Create();
    case 1:
      return DES.Create();
    case 2:
      return Rijndael.Create();
    default:
      throw new NotSupportedException("unknown algorithm");
  }
}

您可以从其余代码中轻松找出如何使用这种新方法。

于 2012-09-09T08:44:37.300 回答