using System.Globalization; namespace Umbraco.Cms.Core; /// /// Used to create a .NET HashCode from multiple objects. /// /// /// .Net has a class the same as this: System.Web.Util.HashCodeCombiner and of course it works for all sorts of things /// which we've not included here as we just need a quick easy class for this in order to create a unique /// hash of directories/files to see if they have changed. /// NOTE: It's probably best to not relying on the hashing result across AppDomains! If you need a constant/reliable /// hash value /// between AppDomains use SHA1. This is perfect for hashing things in a very fast way for a single AppDomain. /// public class HashCodeCombiner { private long _combinedHash = 5381L; public void AddInt(int i) => _combinedHash = ((_combinedHash << 5) + _combinedHash) ^ i; public void AddObject(object o) => AddInt(o.GetHashCode()); public void AddDateTime(DateTime d) => AddInt(d.GetHashCode()); public void AddString(string s) { if (s != null) { AddInt(StringComparer.InvariantCulture.GetHashCode(s)); } } public void AddCaseInsensitiveString(string s) { if (s != null) { AddInt(StringComparer.InvariantCultureIgnoreCase.GetHashCode(s)); } } public void AddFileSystemItem(FileSystemInfo f) { // if it doesn't exist, don't proceed. if (!f.Exists) { return; } AddCaseInsensitiveString(f.FullName); AddDateTime(f.CreationTimeUtc); AddDateTime(f.LastWriteTimeUtc); // check if it is a file or folder if (f is FileInfo fileInfo) { AddInt(fileInfo.Length.GetHashCode()); } if (f is DirectoryInfo dirInfo) { foreach (FileInfo d in dirInfo.GetFiles()) { AddFile(d); } foreach (DirectoryInfo s in dirInfo.GetDirectories()) { AddFolder(s); } } } public void AddFile(FileInfo f) => AddFileSystemItem(f); public void AddFolder(DirectoryInfo d) => AddFileSystemItem(d); /// /// Returns the hex code of the combined hash code /// /// public string GetCombinedHashCode() => _combinedHash.ToString("x", CultureInfo.InvariantCulture); }