Obtener el hash de un archivo

Esto es un ejemplo de como obtener distintos tipos de hash de un archivo,  me apoyaré en una de las nuevas características de C# 3.0, los métodos extensores, para tener más a mano esta funcionalidad. Como se puede ver en el código implementar nuevos métodos para la obtención de otros tipos de hash es sumamente sencillo.

Hay distintos tipos de hash, en este ejemplo he utilizado MD5y dos versiones de SHA, SHA-1 y SHA256. La necesidad y cualidades de cada uno nos dirán que usar en cada momento.

Estos métodos extienden la funcionalidad de la clase FileStream:

static class FileStreamExtensions
{
    public static String GetMd5Hash(this FileStream fs)
    {
        return getHash(fs, new MD5CryptoServiceProvider());
    }
 
    public static String GetSha1Hash(this FileStream fs)
    {
        return getHash(fs, new SHA1Managed());
    }
 
    public static String GetSha256Hash(this FileStream fs)
    {
        return getHash(fs, new SHA256Managed());
    }
 
    private static String getHash(FileStream fs, HashAlgorithm hash)
    {
        Int64 currentPos = fs.Position;
        try
        {
            fs.Seek(0, SeekOrigin.Begin);
            StringBuilder sb = new StringBuilder();
            foreach (Byte b in hash.ComputeHash(fs))
            {
                sb.Append(b.ToString("X2"));
            }
            return sb.ToString();
        }
        finally
        {
            fs.Seek(currentPos, SeekOrigin.Begin);
        }
    }
}

Cuando delcaremos el namespace de esta clase en nuestra unidad, podemos acceder a los métodos y obtener directamente el hash deseado de un tiro 😀

static void Main(string[] args)
{
    FileStream fs = new FileStream(@"C:mylife.mp3",FileMode.Open);
    Console.WriteLine(fs.GetMd5Hash());
    Console.WriteLine(fs.GetSha1Hash());
    Console.WriteLine(fs.GetSha256Hash());
    fs.Close();
    Console.ReadKey(true);
}

Si extendiesemos directamente la clase Stream tendriamos el problema de que a alguien se le podría ocurrir hacerlo sobre un NetworkStream… con lo que tendríamos una excepción ya que no todos los tipos de Stream soportan Seek 😉

 

Obtener el hash de un archivo | vtortola.NET

5 comentarios sobre “Obtener el hash de un archivo”

  1. Esto es un ejemplo de porque no me gusta los extensores de métodos. Realizar un hash de un stream no es algo que tiene que involucrar al stream. El stream tiene su propósito. A veces a la gente se le olvida el principio de responsabilidad única.

  2. Bueno, te pueden gustar ó no gustar, lo que esta claro es lo útiles que son cuando se usan bien. El Stream tiene su función, como todas las clases del .NET Framework, cuando necesitas extender la funcionalidad… la extiendes 🙂

    Realizar un hash de un Stream involucra al Stream, porque se obtiene un hash de ese mismo Stream. No veo el problema. Como realizar un Trim() de un String involucra al String. Únicamente estoy añadiendo una funcionalidad.

  3. Porque no debería serlo? Trim() es una función que claramente se aplica a una cadena. Es que según mi razonamiento si debería ser.

Responder a vtortola Cancelar respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *