2009-04-17 21 views
5

Los objetos que se derivan de HashAlgorithm como MD5CryptoServiceProvider tienen un método Dispose(), pero es privado. En cambio, tiene un método Clear() que "Libera todos los recursos" que usa..NET: deshacerse de un objeto HashAlgorithm

WTF?

¿Es así como desechar correctamente un HashAlgorithm?

var hasher = new MD5CryptoServiceProvider(); 

byte[] hashCode = hasher.ComputeHash(data); 

hasher.Clear(); 

¿Alguien me quiere explicar este? :)

+0

Yo recomiendo usar otro algoritmo hash también si puedes, ya que muchos consideran la MD5 hash inseguro en ciertas aplicaciones. Una buena alternativa sería la familia SHA, como SHA 256. También están disponibles para su uso en .NET. – Skurmedel

+0

Buena llamada. Recuerdo que leer MD5 había demostrado ser vulnerable hace unos años. Geeze, esto de la Wikipedia: "El 18 de marzo de 2006, Klima publicó un algoritmo [10] que puede encontrar una colisión dentro de un minuto en una sola computadora portátil, utilizando un método que llama tunelización". – core

Respuesta

3

Buscando con Reflector, el método Clear de HashAlgorithm simplemente llama al método privado Dispose. La razón para exponer un método con el nombre Clear fue probablemente que los diseñadores de la clase pensaron que sería un nombre más adecuado para un algoritmo hash. Ve estilos similares dentro de otras partes del BCL, como Close para System.IO.Stream. Además, la mejor práctica aquí es utilizar un bloque using, que automáticamente llamará al método privado Dispose cuando haya finalizado.

+0

Como mencionaron otros, es mejor usar un bloque 'using' de todos modos, lo que simplifica la lógica try-finally/dispose para ti, y es una práctica recomendada. – Noldorin

-4

Debe dejar que el GC lo haga por usted. Ese es su trabajo.

Algunos recursos deben desecharse, como las conexiones de BD y los identificadores de archivos, por lo tanto, colóquelos en un bloque using (C#). Este no es uno de esos casos, sin embargo.

+0

En realidad, HashAlgorithm (y por lo tanto MD5CryptoServiceProvider) * do * implementa IDisposable, por lo tanto, deben eliminarse correctamente, ya sea llamando al método Clear o con un bloque 'using'. – Noldorin

+3

El hecho de que la clase implementa IDisposable, no significa que deba eliminarse manualmente. A cada cual, lo suyo. –

+0

No, de hecho, pero el hecho de que * lo * implementa IDisposable casi siempre significa que debe eliminarse manualmente porque está haciendo una interoperación nativa dentro. El GC eventualmente se encargará de deshacerse de él incluso si no llama explícitamente al método, pero el momento en el que esto ocurre no está garantizado pronto – Noldorin

10

Mientras que el método Dipose() es privado, si lo transfiere al IDisposable, puede obtener acceso a él. Sin embargo, como han dicho otros, Clear() lo llamará por usted.

Un mejor enfoque, sin embargo, es encerrar la declaración y y asignación de la variable en a) bloque usando (:

byte[] hashCode; 

using(var hasher = new MD5CryptoServiceProvider()) 
{ 
    hashCode = hasher.ComputeHash(data); 
} 
Cuestiones relacionadas