2012-09-09 34 views
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?我要對這個完全錯誤的標題## ##

回答

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:更新爲使用創建方法而不是屬性,因爲操作的結果將在每次訪問時創建新算法。

+0

您應該爲此使用一個接口而不是抽象基類。 –

+0

@WillVousden - 它會剪掉一大堆語法。 – ChaosPandion

+0

@WillVousden好點。我同意。 –

2

那麼,我的第一個傾向是給你維基百科鏈接到factory methodabstract factory模式(在那裏,我仍然這樣做),但既然你說你是初學者,那麼就不要提前拿出大把的槍。

基本上,你需要的是找到所有加密算法的共同特點,並創建一個方法,它將返回一個具有這種共同特徵的對象實例。這種特性的表現形式可以是抽象類或C#中的接口,並且幸運的是,所有選定的加密都來自SymmetricAlgorithm(「運氣」可能是對System.Security.Cryptography設計人員的侮辱,但我確信他們會爲了插圖而原諒我)。

所以,只要refactor你的代碼通過引入新的方法,可能沿着這些線路:

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"); 
    } 
} 

你可以很容易弄清楚如何使用這種新方法從你的代碼的其餘部分。

+0

我可以欣賞這種設計的簡單性。 – ChaosPandion

+0

@ChaosPandion:謝謝。我認爲其他答案雖然可能從面向對象的角度來看更好,但對初學者來說可能會令人望而生畏。一步一個腳印,激起他們的胃口:) – Alan

+0

非常感謝!我認爲這會起作用,並且切換案件是我知道的! C#與我所瞭解的編程語言完全不同,所以它已經習慣了一些。謝謝你的支持。 – user1657838