using System.Globalization; using System.Security.Cryptography; using System.Text; namespace Domain.Helpers { public interface IComparableByHash { IEnumerable<object> GetHashDependencies(); } public interface IHashComparer { bool IsEqualTo(IComparableByHash other); } public static class HashHelpers { public static IEnumerable<object> SelectDependencies(params object[] dependencies) => dependencies; public static string GetHash(this IComparableByHash src) => Sha1FromDependencies(src.GetHashDependencies()); public static IHashComparer Compare(IComparableByHash src) => new HashComparer(src); public static string Sha1FromDependencies(IEnumerable<object> dependencies) => GetSHA1(string.Join(";", dependencies.Select(x => Convert.ToString(x, CultureInfo.InvariantCulture)?.Trim()))); public static string GetMD5(string data) => GetHash(MD5.Create(), data); public static string GetSHA1(string data) => GetHash(SHA1.Create(), data); public static string GetSHA256(string data) => GetHash(SHA256.Create(), data); public static string GetSHA384(string data) => GetHash(SHA384.Create(), data); public static string GetSHA512(string data) => GetHash(SHA512.Create(), data); public static string GetSHA1Guid(string data) { // SHA1 = 2fd4e1c67a2d28fced849ee1bb76e7391b93eb12 // Guid = {3f2504e0-4f89-11d3-9a0c-0305e82c3301} string sha1 = GetSHA1(data); string[] parts = new string[] { sha1.Substring(0,8), sha1.Substring(8,4), sha1.Substring(12,4), sha1.Substring(16,4), sha1.Substring(20,12) }; return string.Join("-", parts); } public static string GetHash(HashAlgorithm algoritm, string data) { byte[] inputBytes = Encoding.UTF8.GetBytes(data); byte[] hashBytes = algoritm.ComputeHash(inputBytes); // Convert the byte array to hexadecimal string var sb = new StringBuilder(); for (int i = 0; i < hashBytes.Length; i++) { sb.Append(hashBytes[i].ToString("x2")); // For uppercase use: X2 } return sb.ToString(); } private class HashComparer : IHashComparer { private readonly string sourceHash; public HashComparer(IComparableByHash item) { sourceHash = item?.GetHash(); } public bool IsEqualTo(IComparableByHash other) { if (sourceHash == null || other == null) return false; return sourceHash == other?.GetHash(); } } } }
public class MyItem : IComparableByHash { public Guid? Id { get; set; } public string Description { get;set; } public double Amount { get; set; } public int Priority { get; set; } IEnumerable<object> IComparableByHash.GetHashDependencies() => HashHelpers.SelectDependencies(Description, Amount, Priority); } itemsToImport.Select(y => { var existing = existingItems.FirstOrDefault(x => x.Id == y.Id); var comparer = HashHelpers.Compare(existing); existing ??= new MyItem(); existing.Description = item.Description; existing.Amount = item.Amount; existing.Priority = item.Priority; if (comparer.IsEqualTo(existing)) return null; return existing; }) .Where(x => x != null) .ToList();
11700cookie-checkC# HashHelpers