using System; using System.Collections.Generic; using System.Linq; using System.Security.Cryptography; using System.Text; using System.Threading.Tasks; namespace OpenSaveCloudClient.Core { internal class HashTool { /// /// method HashDirectory walk through a directory and make a hash of all the files /// /// The path to the folder /// The hash of the folder /// public static byte[]? HashDirectory(string path) { DirectoryInfo dir = new(path); using HashAlgorithm? sha = HashAlgorithm.Create("SHA-512"); if (sha == null) { throw new InvalidOperationException("HashDirectory: SHA-512 algorithm does not exist"); } using (var stream = new CryptoStream(Stream.Null, sha, CryptoStreamMode.Write)) { using var writer = new BinaryWriter(stream); FileSystemInfo[] infos = dir.GetFileSystemInfos(); Array.Sort(infos, (a, b) => string.Compare(a.Name, b.Name, StringComparison.Ordinal)); foreach (FileSystemInfo info in infos) { writer.Write(info.Name); if ((info.Attributes & FileAttributes.Directory) == 0) { byte[]? hash = HashFile(info as FileInfo); if (hash == null) { throw new InvalidOperationException("HashDirectory: hash of the file is null"); } writer.Write((byte)'F'); writer.Write(hash); } else { byte[]? hash = HashDirectory(info.FullName); if (hash == null) { throw new InvalidOperationException("HashDirectory: hash of the directory is null"); } writer.Write((byte)'D'); writer.Write(hash); } } } return sha.Hash; } /// /// method HashFile make a hash SHA-512 of a file /// /// The file information /// The file's hash /// /// private static byte[]? HashFile(FileInfo? fileInfo) { if (fileInfo == null) { throw new Exception("HashFile: invalid file information"); } using HashAlgorithm? sha = HashAlgorithm.Create("SHA-512"); if (sha == null) { throw new InvalidOperationException("HashFile: SHA-512 algorithm does not exist"); } using var inputStream = fileInfo.OpenRead(); return sha.ComputeHash(inputStream); } } }