{"id":117,"date":"2016-03-19T11:40:15","date_gmt":"2016-03-19T10:40:15","guid":{"rendered":"https:\/\/solidt.eu\/blog\/?p=117"},"modified":"2024-10-07T14:23:21","modified_gmt":"2024-10-07T13:23:21","slug":"c-hashhelpers","status":"publish","type":"post","link":"https:\/\/solidt.eu\/site\/c-hashhelpers\/","title":{"rendered":"C# HashHelpers"},"content":{"rendered":"\n<div style=\"height: 250px; position:relative; margin-bottom: 50px;\" class=\"wp-block-simple-code-block-ace\"><pre class=\"wp-block-simple-code-block-ace\" style=\"position:absolute;top:0;right:0;bottom:0;left:0\" data-mode=\"csharp\" data-theme=\"monokai\" data-fontsize=\"14\" data-lines=\"Infinity\" data-showlines=\"true\" data-copy=\"false\">using System.Globalization;\nusing System.Security.Cryptography;\nusing System.Text;\n\nnamespace Domain.Helpers\n{\n    public interface IComparableByHash\n    {\n        IEnumerable&lt;object> GetHashDependencies();\n    }\n\n    public interface IHashComparer\n    {\n        bool IsEqualTo(IComparableByHash other);\n    }\n\n    public static class HashHelpers\n    {\n        public static IEnumerable&lt;object> SelectDependencies(params object[] dependencies) => dependencies;\n        public static string GetHash(this IComparableByHash src) => Sha1FromDependencies(src.GetHashDependencies());\n        public static IHashComparer Compare(IComparableByHash src) => new HashComparer(src);\n\n        public static string Sha1FromDependencies(IEnumerable&lt;object> dependencies) => GetSHA1(string.Join(\";\", dependencies.Select(x => Convert.ToString(x, CultureInfo.InvariantCulture)?.Trim())));\n\n        public static string GetMD5(string data) => GetHash(MD5.Create(), data);\n        public static string GetSHA1(string data) => GetHash(SHA1.Create(), data);\n        public static string GetSHA256(string data) => GetHash(SHA256.Create(), data);\n        public static string GetSHA384(string data) => GetHash(SHA384.Create(), data);\n        public static string GetSHA512(string data) => GetHash(SHA512.Create(), data);\n\n        public static string GetSHA1Guid(string data)\n        {\n            \/\/ SHA1 = 2fd4e1c67a2d28fced849ee1bb76e7391b93eb12\n            \/\/ Guid = {3f2504e0-4f89-11d3-9a0c-0305e82c3301}\n            string sha1 = GetSHA1(data);\n            string[] parts = new string[] {\n                sha1.Substring(0,8),\n                sha1.Substring(8,4),\n                sha1.Substring(12,4),\n                sha1.Substring(16,4),\n                sha1.Substring(20,12)\n            };\n            return string.Join(\"-\", parts);\n        }\n\n        public static string GetHash(HashAlgorithm algoritm, string data)\n        {\n            byte[] inputBytes = Encoding.UTF8.GetBytes(data);\n            byte[] hashBytes = algoritm.ComputeHash(inputBytes);\n            \/\/ Convert the byte array to hexadecimal string\n            var sb = new StringBuilder();\n            for (int i = 0; i &lt; hashBytes.Length; i++)\n            {\n                sb.Append(hashBytes[i].ToString(\"x2\")); \/\/ For uppercase use: X2\n            }\n            return sb.ToString();\n        }\n\n        private class HashComparer : IHashComparer\n        {\n            private readonly string sourceHash;\n\n            public HashComparer(IComparableByHash item)\n            {\n                sourceHash = item?.GetHash();\n            }\n\n            public bool IsEqualTo(IComparableByHash other)\n            {\n                if (sourceHash == null || other == null) return false;\n                return sourceHash == other?.GetHash();\n            }\n        }\n    }\n}\n<\/pre><\/div>\n\n\n\n<div style=\"height: 250px; position:relative; margin-bottom: 50px;\" class=\"wp-block-simple-code-block-ace\"><pre class=\"wp-block-simple-code-block-ace\" style=\"position:absolute;top:0;right:0;bottom:0;left:0\" data-mode=\"csharp\" data-theme=\"monokai\" data-fontsize=\"14\" data-lines=\"Infinity\" data-showlines=\"true\" data-copy=\"false\">public class MyItem : IComparableByHash\n{\n    public Guid? Id { get; set; }\n    public string Description { get;set; }\n    public double Amount { get; set; }\n    public int Priority { get; set; }\n\n    IEnumerable&lt;object> IComparableByHash.GetHashDependencies() => HashHelpers.SelectDependencies(Description, Amount, Priority);\n}\n\nitemsToImport.Select(y =>\n{\n    var existing = existingItems.FirstOrDefault(x => x.Id == y.Id);\n    var comparer = HashHelpers.Compare(existing);\n    \n    existing ??= new MyItem();\n    existing.Description = item.Description;\n    existing.Amount = item.Amount;\n    existing.Priority = item.Priority;\n    \n    if (comparer.IsEqualTo(existing)) return null;\n    return existing;\n})\n.Where(x => x != null)\n.ToList();<\/pre><\/div>\n","protected":false},"excerpt":{"rendered":"","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"inline_featured_image":false,"footnotes":""},"categories":[6],"tags":[],"class_list":["post-117","post","type-post","status-publish","format-standard","hentry","category-dotnet"],"_links":{"self":[{"href":"https:\/\/solidt.eu\/site\/wp-json\/wp\/v2\/posts\/117","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/solidt.eu\/site\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/solidt.eu\/site\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/solidt.eu\/site\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/solidt.eu\/site\/wp-json\/wp\/v2\/comments?post=117"}],"version-history":[{"count":7,"href":"https:\/\/solidt.eu\/site\/wp-json\/wp\/v2\/posts\/117\/revisions"}],"predecessor-version":[{"id":8953,"href":"https:\/\/solidt.eu\/site\/wp-json\/wp\/v2\/posts\/117\/revisions\/8953"}],"wp:attachment":[{"href":"https:\/\/solidt.eu\/site\/wp-json\/wp\/v2\/media?parent=117"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/solidt.eu\/site\/wp-json\/wp\/v2\/categories?post=117"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/solidt.eu\/site\/wp-json\/wp\/v2\/tags?post=117"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}