什麼是C#中的最佳解決方案計算的「對飛」 MD5像未知長度的流的哈希?具體來說,我想從網絡上收到的數據計算一個散列。我知道當發送者終止連接時我已經接收到了數據,所以我不知道這個長度。計算從未知長度的流在C#中的哈希
[編輯] - 現在我使用MD5,但這需要在數據第二遍後,它被保存並寫入磁盤。我寧願將它散列到網絡中。
什麼是C#中的最佳解決方案計算的「對飛」 MD5像未知長度的流的哈希?具體來說,我想從網絡上收到的數據計算一個散列。我知道當發送者終止連接時我已經接收到了數據,所以我不知道這個長度。計算從未知長度的流在C#中的哈希
[編輯] - 現在我使用MD5,但這需要在數據第二遍後,它被保存並寫入磁盤。我寧願將它散列到網絡中。
MD5,像其他散列函數,不需要兩遍。
要啓動:
HashAlgorithm hasher = ..;
hasher.Initialize();
作爲每個數據塊到達時:
byte[] buffer = ..;
int bytesReceived = ..;
hasher.TransformBlock(buffer, 0, bytesReceived, null, 0);
要完成並檢索散列:
hasher.TransformFinalBlock(new byte[0], 0, 0);
byte[] hash = hasher.Hash;
這種模式適用於衍生自任何類型的其中包括MD5CryptoServiceProvider
和SHA1Managed
。
HashAlgorithm
也定義了一個方法ComputeHash
,它需要一個Stream
對象;然而,這個方法會阻塞線程,直到流被使用。使用TransformBlock
方法允許在數據到達時計算出「異步散列」,而無需使用線程。
的System.Security.Cryptography.MD5類包含一個ComputeHash方法,該方法它可以是一個字節[]或流。瞧瞧吧http://msdn.microsoft.com/en-us/library/system.security.cryptography.md5_members.aspx
繼@彼得 - mourfield的答案,這裏是使用ComputeHash()
代碼:
private static string CalculateMd5(string filePathName) {
using (var stream = File.OpenRead(filePathName))
using (var md5 = MD5.Create()) {
var hash = md5.ComputeHash(stream);
var base64String = Convert.ToBase64String(hash);
return base64String;
}
}
由於兩個流以及MD5實現IDisposible,你需要使用using(...){...}
的代碼示例中的方法返回用於Azure Blob存儲中的MD5校驗和的相同字符串。
Necromancing。
兩個possibilitites在C#.NET核心:
private static System.Security.Cryptography.HashAlgorithm GetHashAlgorithm(System.Security.Cryptography.HashAlgorithmName hashAlgorithmName)
{
if (hashAlgorithmName == System.Security.Cryptography.HashAlgorithmName.MD5)
return (System.Security.Cryptography.HashAlgorithm) System.Security.Cryptography.MD5.Create();
if (hashAlgorithmName == System.Security.Cryptography.HashAlgorithmName.SHA1)
return (System.Security.Cryptography.HashAlgorithm) System.Security.Cryptography.SHA1.Create();
if (hashAlgorithmName == System.Security.Cryptography.HashAlgorithmName.SHA256)
return (System.Security.Cryptography.HashAlgorithm) System.Security.Cryptography.SHA256.Create();
if (hashAlgorithmName == System.Security.Cryptography.HashAlgorithmName.SHA384)
return (System.Security.Cryptography.HashAlgorithm) System.Security.Cryptography.SHA384.Create();
if (hashAlgorithmName == System.Security.Cryptography.HashAlgorithmName.SHA512)
return (System.Security.Cryptography.HashAlgorithm) System.Security.Cryptography.SHA512.Create();
throw new System.Security.Cryptography.CryptographicException($"Unknown hash algorithm \"{hashAlgorithmName.Name}\".");
}
protected override byte[] HashData(System.IO.Stream data,
System.Security.Cryptography.HashAlgorithmName hashAlgorithm)
{
using (System.Security.Cryptography.HashAlgorithm hashAlgorithm1 =
GetHashAlgorithm(hashAlgorithm))
return hashAlgorithm1.ComputeHash(data);
}
或BouncyCastle的:
private static Org.BouncyCastle.Crypto.IDigest GetBouncyAlgorithm(
System.Security.Cryptography.HashAlgorithmName hashAlgorithmName)
{
if (hashAlgorithmName == System.Security.Cryptography.HashAlgorithmName.MD5)
return new Org.BouncyCastle.Crypto.Digests.MD5Digest();
if (hashAlgorithmName == System.Security.Cryptography.HashAlgorithmName.SHA1)
return new Org.BouncyCastle.Crypto.Digests.Sha1Digest();
if (hashAlgorithmName == System.Security.Cryptography.HashAlgorithmName.SHA256)
return new Org.BouncyCastle.Crypto.Digests.Sha256Digest();
if (hashAlgorithmName == System.Security.Cryptography.HashAlgorithmName.SHA384)
return new Org.BouncyCastle.Crypto.Digests.Sha384Digest();
if (hashAlgorithmName == System.Security.Cryptography.HashAlgorithmName.SHA512)
return new Org.BouncyCastle.Crypto.Digests.Sha512Digest();
throw new System.Security.Cryptography.CryptographicException(
$"Unknown hash algorithm \"{hashAlgorithmName.Name}\"."
);
} // End Function GetBouncyAlgorithm
protected override byte[] HashData(System.IO.Stream data,
System.Security.Cryptography.HashAlgorithmName hashAlgorithm)
{
Org.BouncyCastle.Crypto.IDigest digest = GetBouncyAlgorithm(hashAlgorithm);
byte[] buffer = new byte[4096];
int cbSize;
while ((cbSize = data.Read(buffer, 0, buffer.Length)) > 0)
digest.BlockUpdate(buffer, 0, cbSize);
byte[] hash = new byte[digest.GetDigestSize()];
digest.DoFinal(hash, 0);
return hash;
}
我看到了這些方法,但從來沒有調查他們做了什麼。對我感到羞恥。這看起來像會起作用。 – jjxtra 2010-09-01 19:13:26