2010-01-03 7 views

Respuesta

56

Con el método ComputeHash. Ver aquí:

ComputeHash

fragmento de ejemplo:

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

    //do something with hash 
} 

Dónde buffer es el contenido de su archivo.

+4

+1 para un gran consejo sobre el uso del 'BitConverter' para generar un hexágono-secuencia de una sola vez. –

+1

SHA1CryptoServiceProvider debe estar envuelto en un bloque 'using' – Mike737

+1

' BitConverter' separa bytes con un guion AA-F0-CC a diferencia de la solución de @ mgbowen. Puede o no ser lo que se desea. –

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 representación de cadena del hash SHA-1. Además, al usar un FileStream en lugar de un búfer de bytes, ComputeHash calcula el hash en fragmentos, por lo que no tiene que cargar todo el archivo de una vez, lo que es útil para archivos de gran tamaño.

+3

Debería usar un 'StringBuilder' en lugar de generar 20 cadenas en el proceso de compilación de la cadena hash. –

+0

'FileStream' es' IDisposable' y también debe usarse en un bloque 'using'. –

+3

La capacidad inicial de StringBuilder debe ser el doble de la cantidad de bytes en el hash –

4

Si ya está leyendo el archivo como una secuencia, la siguiente técnica calcula el hash a medida que lo lee. La única advertencia es que necesitas consumir toda la secuencia.

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 para 'CryptoStream'. podría ser útil en caso de que desee leer un archivo de alguna parte (p. ej., de una solicitud http), escribirlo en algún lugar (p. ej .: en el disco) y, al mismo tiempo, calcular el hash. – tigrou

+1

En una prueba en un archivo grande, este código realiza órdenes de magnitud peor que las soluciones 'ComputeHash'. ¿Tal vez es la lectura individual de "ReadByte"? –

+0

@MichaelKropat interesante. Bueno saber. 10 veces, 100 veces más lento? –

0

También puede probar:

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