using System.Collections.Generic;
public List<ComparisonGroup> ComparisonGroups { get; set; }
public string MD5Hash { get; set; }
private class ComparisonGroup
public int Sequence { get; set; }
public List<int> Ids { get; set; }
public static void Main()
var records = new Comparison[]
foreach (var r in records)
r.MD5Hash = HashComparison(r);
var orderedDup = OrderedComparison(dup);
var dupHash = HashComparison(orderedDup);
var matches = records.Where(r => r.MD5Hash == dupHash);
Console.WriteLine(matches.Any(r => {
if (r.ComparisonGroups.Count != orderedDup.ComparisonGroups.Count)
for (var i = 0; i < r.ComparisonGroups.Count; i++)
var rcg = r.ComparisonGroups[i];
var dcg = orderedDup.ComparisonGroups[i];
if (rcg.Sequence != dcg.Sequence || !Enumerable.SequenceEqual(rcg.Ids, dcg.Ids))
public static string CreateMD5(string input)
using (System.Security.Cryptography.MD5 md5 = System.Security.Cryptography.MD5.Create())
byte[] inputBytes = System.Text.Encoding.ASCII.GetBytes(input);
byte[] hashBytes = md5.ComputeHash(inputBytes);
StringBuilder sb = new StringBuilder();
for (int i = 0; i < hashBytes.Length; i++)
sb.Append(hashBytes[i].ToString("X2"));
private static string HashComparison(Comparison c)
return CreateMD5(SerializeComparison(c));
private static string SerializeComparison(Comparison c)
return String.Join("|", c.ComparisonGroups.Select(cg => cg.Sequence.ToString() + "|" + String.Join("|", cg.Ids)));
private static Comparison OrderedComparison(Comparison c)
ComparisonGroups = c.ComparisonGroups
.OrderBy(grp => grp.Sequence)
.Select(grp => new ComparisonGroup
Ids = grp.Ids.OrderBy(id => id).ToList()