2016-08-15 32 views
0

目前我有3種不同的方法用於md5,sha1和sha512。一些小部件是不同的,比如使用聲明。是否有可能爲所有這些創建一個通用方法?我是一箇中級人員,有些話題對我來說很新。 下面的代碼(簡體)。忽略「ConvertHashToString」方法。 謝謝!任何算法的C#密碼通用方法

public string CheckMd5(string filename) 
    { 
     using (var stream = File.OpenRead(filename)) 
     { 
      using (var md5 = MD5.Create()) 
      { 
       return ConvertHashToString(md5.ComputeHash(stream)); 
      } 
     } 

    } 

    public string CheckSha512(string filename) 
    { 
     using (var stream = File.OpenRead(filename)) 
     { 
      using (var sha = SHA512.Create()) 
      { 
       return ConvertHashToString(sha.ComputeHash(stream)); 
      } 
     } 
    } 

回答

1

您可以簡化它有點像這樣:

private string CheckHash(string filename, HashAlgorithm algorithm) 
{ 
    using (var stream = File.OpenRead(filename)) 
    { 
     using (algorithm) 
     { 
      return ConvertHashToString(algorithm.ComputeHash(stream)); 
     } 
    } 
} 

public string CheckMd5(string filename) => CheckHash(filename, MD5.Create()); 

public string CheckSha512(string filename) => CheckHash(filename, SHA512.Create()); 

如果你想一個方法,你需要指定算法的一些方法。您還可以使用CryptoConfig.CreateFromName從字符串創建哈希實例。事情是這樣的:

public string CheckHash(string filename, string algorithm) 
{ 
    using (var stream = File.OpenRead(filename)) 
    { 
     using (var algorithm = (HashAlgorithm)CryptoConfig.CreateFromName(algorithm)) 
     { 
      return ConvertHashToString(algorithm.ComputeHash(stream)); 
     } 
    } 
} 

你可能想驗證CryptoConfig.CreateFromName試圖施放前返回HashAlgorithm

最後,您可以使用泛型,但這不使用工廠方法。工廠方法在.NET Core方案中效果更好,但是因爲您使用的是WinForms,所以聽起來這不是一個問題。

public string Check<THash>(string filename) where THash:HashAlgorithm, new() 
{ 
    using (var stream = File.OpenRead(filename)) 
    { 
     using (var algorithm = new THash()) 
     { 
      return ConvertHashToString(algorithm.ComputeHash(stream)); 
     } 
    } 
} 

哪位能像這樣被使用:

CheckHash<SHA512Managed>(file); 
+0

謝謝!這種方式的名字是什麼?匿名方法? – schui

+0

第一個只是一些新的C#6語法,稱爲[表達式體成員](https://msdn.microsoft.com/en-us/magazine/dn802602.aspx)。 – vcsjones

+0

第一種實現通常是不好的做法。對象應該在創建它們的地方放置。在示例中,我將一個完全有效的'MD5'對象傳遞給'CheckHash',但在調用'CheckHash'後,我的'MD5'對象因某種原因被丟棄。如果我打算再次使用它,該怎麼辦?沒有任何關於'CheckHash'的信息會指出這種行爲。 – dman2306