2010-01-03 13 views

risposta

56

Con il metodo ComputeHash. Vedi qui:

ComputeHash

frammento di esempio:

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

    //do something with hash 
} 

Dove buffer è il contenuto del file.

+4

+1 per una grande punta sull'utilizzo del 'BitConverter' per generare un hex-stringa in un colpo solo. –

+1

SHA1CryptoServiceProvider deve essere racchiuso in un blocco 'using' – Mike737

+1

' BitConverter' separa i byte con un trattino AA-F0-CC a differenza della soluzione di @ mgbowen. Può o non può essere quello che si desidera. –

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 contiene la rappresentazione di stringa dell'hash SHA-1. Inoltre, utilizzando un FileStream anziché un buffer di byte, lo ComputeHash calcola l'hash in blocchi, quindi non è necessario caricare l'intero file in una volta sola, il che è utile per file di grandi dimensioni.

+3

È necessario utilizzare un 'StringBuilder' invece di generare 20 stringhe nel processo di creazione della stringa hash. –

+0

'FileStream' è' IDisposable' e dovrebbe essere usato anche in un blocco 'using'. –

+3

La capacità iniziale di StringBuilder deve essere il doppio del numero di byte nell'hash –

4

Se stai già leggendo il file come uno stream, la tecnica seguente calcola l'hash mentre lo leggi. L'unica avvertenza è che è necessario consumare l'intero flusso.

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 per 'CryptoStream'. potrebbe essere utile nel caso in cui tu voglia leggere un file da qualche parte (ad es .: da una richiesta http), scriverlo in qualche posto (es .: su disco) e allo stesso tempo calcolare l'hash. – tigrou

+1

In un test su un file di grandi dimensioni, questo codice ha eseguito ordini di grandezza peggiori rispetto alle soluzioni 'ComputeHash'. Forse è la lettura "alla volta di ReadByte"? –

+0

@MichaelKropat interessante. Buono a sapersi. 10 volte, 100 volte più lento? –

0

Inoltre si può provare:

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