I need to create the hash for a folder that contains some files. I've already done this task for each of the files, but I'm searching for a way to create one hash for all files in a folder. Any ideas on how to do that?
(Of course I can create the hash for each file and concatenate it to some big hash but it's not a way I like)
HASHING. In multi-Director Hashing (MDH), a set of hash directories is used to access a file. The number of hash directories is fixed and each directory grows and shrinks dynamically in the same way as the directory of extendible hashing.
This hashes all file (relative) paths and contents, and correctly handles file ordering.
And it's quick - like 30ms for a 4MB directory.
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(); }
Dunc's answer works well; however, it does not handle an empty directory. The code below returns the MD5 'd41d8cd98f00b204e9800998ecf8427e' (the MD5 for a 0 length character stream) for an empty directory.
public static string CreateDirectoryMd5(string srcPath) { var filePaths = Directory.GetFiles(srcPath, "*", SearchOption.AllDirectories).OrderBy(p => p).ToArray(); using (var md5 = MD5.Create()) { foreach (var filePath in filePaths) { // hash path byte[] pathBytes = Encoding.UTF8.GetBytes(filePath); md5.TransformBlock(pathBytes, 0, pathBytes.Length, pathBytes, 0); // hash contents byte[] contentBytes = File.ReadAllBytes(filePath); md5.TransformBlock(contentBytes, 0, contentBytes.Length, contentBytes, 0); } //Handles empty filePaths case md5.TransformFinalBlock(new byte[0], 0, 0); return BitConverter.ToString(md5.Hash).Replace("-", "").ToLower(); } }
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With