Esto comprime todas las rutas y contenidos de archivos (relativos) y maneja correctamente el orden de archivos.
Y es rápido, como 30ms para un directorio de 4MB.
using System;
using System.Text;
using System.Security.Cryptography;
using System.IO;
using System.Linq;
...
public static string CreateMd5ForFolder(string path)
{
// assuming you want to include nested folders
var files = Directory.GetFiles(path, "*.*", SearchOption.AllDirectories)
.OrderBy(p => p).ToList();
MD5 md5 = MD5.Create();
for(int i = 0; i < files.Count; i++)
{
string file = files[i];
// hash path
string relativePath = file.Substring(path.Length + 1);
byte[] pathBytes = Encoding.UTF8.GetBytes(relativePath.ToLower());
md5.TransformBlock(pathBytes, 0, pathBytes.Length, pathBytes, 0);
// hash contents
byte[] contentBytes = File.ReadAllBytes(file);
if (i == files.Count - 1)
md5.TransformFinalBlock(contentBytes, 0, contentBytes.Length);
else
md5.TransformBlock(contentBytes, 0, contentBytes.Length, contentBytes, 0);
}
return BitConverter.ToString(md5.Hash).Replace("-", "").ToLower();
}
Gracias por su respuesta. La cuerda puede ser muy grande, así que tendré que dividirla en trozos, solo pensando cómo hacerlo correctamente. –
Recuerdo que los hashers de C# tenían una función para alimentarlos con trozos, y finalmente puedes pedir obtener el hash final, sin estar seguro de cuáles eran estas funciones/clases. Con ellos puede ordenar su entrada de la manera que desee en la memoria, luego buclear archivos y cargar fragmentos en unos cientos de KB y alimentarlos al hasher, de esta manera no necesita mucha memoria, pero aún así, tomará un tiempo para hash, que es algo de lo que no puedes deshacerte. – aularon