Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do you create the hash of a folder in C#?

Tags:

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)

like image 830
Igor Pistolyaka Avatar asked Sep 02 '10 09:09

Igor Pistolyaka


People also ask

What is a hashed directory?

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.


2 Answers

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(); } 
like image 96
Dunc Avatar answered Oct 26 '22 23:10

Dunc


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();     } } 
like image 23
Blake Biggs Avatar answered Oct 26 '22 23:10

Blake Biggs