using System.IO.Enumeration; using System.Security.Cryptography; if (args.Length < 2) { Console.WriteLine("Usage: HashSumJ [parallel:default same to vCpu]"); Console.WriteLine(" algo: MD5 SHA256 SHA512 SHA1"); return -1; } Func hashAlgo = args[0].ToLower() switch { "md5" => MakeMd5FromFilePath, "sha256" => MakeSha256FromFilePath, "sha512" => MakeSha512FromFilePath, "sha1" => MakeSha1FromFilePath, _ => throw new ArgumentException("algo") }; var dirToCheckSum = args[1]; var threads = Environment.ProcessorCount; if (args.Length > 1 && ushort.TryParse(args[1], out var t)) threads = t; var files = new FileSystemEnumerable(dirToCheckSum, (ref FileSystemEntry p) => p.ToFullPath(), new EnumerationOptions { RecurseSubdirectories = true, }) { ShouldIncludePredicate = (ref FileSystemEntry p) => p.IsDirectory == false }; var arrFilesPath = files.ToArray(); var num = 0; Parallel.ForEach(arrFilesPath, new ParallelOptions { MaxDegreeOfParallelism = threads }, f => { try { Console.WriteLine($"{hashAlgo(f)}|{f}|t#{Environment.CurrentManagedThreadId}|{Interlocked.Increment(ref num)} of {arrFilesPath.Length}"); } catch (Exception e) { Console.WriteLine($"Err: {e.Message}"); } }); return 0; static string MakeMd5FromFilePath(string filePath) { using var fs = File.OpenRead(filePath); return Convert.ToHexString(MD5.HashData(fs)); } static string MakeSha1FromFilePath(string filePath) { using var fs = File.OpenRead(filePath); return Convert.ToHexString(SHA1.HashData(fs)); } static string MakeSha256FromFilePath(string filePath) { using var fs = File.OpenRead(filePath); return Convert.ToHexString(SHA256.HashData(fs)); } static string MakeSha512FromFilePath(string filePath) { using var fs = File.OpenRead(filePath); return Convert.ToHexString(SHA512.HashData(fs)); }