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();

編集:抽象基本クラスではなくインターフェイスを使用するというウィルの提案で更新されました。編集 2: 操作の結果、アクセスされるたびに新しいアルゴリズムが作成されるため、プロパティではなく create メソッドを使用するように更新されました。

于 2012-09-09T08:32:51.540 に答える
2

ええと、私の最初の傾向は、ファクトリ メソッド抽象ファクトリパターンへのウィキペディアのリンクを提供することでした (そこで、私はまだそれを行いました)。

基本的に、必要なことは、すべての暗号化アルゴリズムの共通の特性を見つけ、この共通の特性を持つオブジェクト インスタンスを返すメソッドを作成することです。このような特性の明示は、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 に答える