2010-01-03 13 views

Antwort

56

Mit der ComputeHash-Methode. Siehe hier:

ComputeHash

Beispiel Snippet:

using(var cryptoProvider = new SHA1CryptoServiceProvider()) 
{ 
    string hash = BitConverter 
      .ToString(cryptoProvider.ComputeHash(buffer)); 

    //do something with hash 
} 

Wo Puffer der Inhalt der Datei ist.

+4

+1 für eine große Spitze des 'BitConverter' auf dem mit einem Hex-String in einem Rutsch zu erzeugen. –

+1

SHA1CryptoServiceProvider sollte in einen 'using' Block gehüllt sein – Mike737

+1

' BitConverter' trennt Bytes mit einem Strich AA-F0-CC im Gegensatz zu @ mgbowens Lösung. Kann oder darf nicht sein, was gewünscht wird. –

69
using (FileStream fs = new FileStream(@"C:\file\location", FileMode.Open)) 
using (BufferedStream bs = new BufferedStream(fs)) 
{ 
    using (SHA1Managed sha1 = new SHA1Managed()) 
    { 
     byte[] hash = sha1.ComputeHash(bs); 
     StringBuilder formatted = new StringBuilder(2 * hash.Length); 
     foreach (byte b in hash) 
     { 
      formatted.AppendFormat("{0:X2}", b); 
     } 
    } 
} 

formatted enthält die Zeichenfolgendarstellung des SHA-1-Hash. Durch die Verwendung eines anstelle eines Byte-Puffers berechnet den Hash in Chunks, sodass Sie nicht die gesamte Datei auf einmal laden müssen, was für große Dateien hilfreich ist.

+3

Sie sollten einen 'StringBuilder' verwenden, anstatt 20 Zeichenfolgen beim Erstellen der Hash-Zeichenfolge zu generieren. –

+0

'FileStream' ist' IDisposable' und sollte auch in einem 'using' Block verwendet werden. –

+3

Die ursprüngliche Kapazität von StringBuilder sollte doppelt so groß sein wie die Anzahl der Bytes im Hash. –

4

Wenn Sie die Datei bereits als Stream lesen, berechnet das folgende Verfahren den Hashwert beim Lesen. Die einzige Einschränkung ist, dass Sie den gesamten Stream verbrauchen müssen.

class Program 
    { 
     static void Main(string[] args) 
     { 
      String sourceFileName = "C:\\test.txt"; 
      Byte[] shaHash; 

      //Use Sha1Managed if you really want sha1 
      using (var shaForStream = new SHA256Managed()) 
      using (Stream sourceFileStream = File.Open(sourceFileName, FileMode.Open)) 
      using (Stream sourceStream = new CryptoStream(sourceFileStream, shaForStream, CryptoStreamMode.Read)) 
      { 
       //Do something with the sourceStream 
       //NOTE You need to read all the bytes, otherwise you'll get an exception ({"Hash must be finalized before the hash value is retrieved."}) 
       while(sourceStream.ReadByte() != -1);     
       shaHash = shaForStream.Hash; 
      } 

      Console.WriteLine(Convert.ToBase64String(shaHash)); 
     } 
    } 
+0

+1 für 'CryptoStream'. es könnte nützlich sein, wenn Sie eine Datei von irgendwo lesen möchten (zB von einer http-Anfrage), sie an einen bestimmten Ort schreiben (zB: auf die Festplatte) und gleichzeitig den Hash berechnen. – tigrou

+1

Bei einem Test in einer großen Datei war dieser Code um Größenordnungen schlechter als die ComputeHash-Lösungen. Vielleicht ist es das 'ReadByte'-Lesebuch? –

+0

@ MichaelKropat interessant. Gut zu wissen. 10 mal, 100 mal langsamer? –

0

Sie können auch versuchen:

FileStream fop = File.OpenRead(@"C:\test.bin"); 
string chksum = BitConverter.ToString(System.Security.Cryptography.SHA1.Create().ComputeHash(fop));