public static IPRanges Negate(IPRange r1, IPRanges negatedRanges) { if (!r1.IsValid()) { return(null); } // merge subnets to negate var mergedNegatedRanges = Merge(negatedRanges).Ranges; var res = new List <IPRange>(); // no overlap if (r1.Maximum < mergedNegatedRanges[0].Minimum || r1.Minimum > mergedNegatedRanges.Last().Maximum) { res.Add(r1); return(new IPRanges(res)); } var lastRange = new IPRange(r1.Minimum, r1.Maximum); foreach (IPRange negatedRange in mergedNegatedRanges) { if (lastRange.Minimum < negatedRange.Minimum) { res.Add(new IPRange(lastRange.Minimum, negatedRange.Minimum - 1)); lastRange.Minimum = negatedRange.Maximum + 1; } else { if (negatedRange.Maximum < lastRange.Minimum) { // do nothing - ignore this range } else { if (negatedRange.Maximum < lastRange.Maximum) { lastRange.Minimum = negatedRange.Maximum + 1; } } } } if (!lastRange.IsEmpty()) { res.Add(lastRange); } return(new IPRanges(res)); }
public static IPRanges Merge(IPRanges rangesToMerge) { if (rangesToMerge.Ranges.Count == 1) { return(new IPRanges(rangesToMerge.Ranges)); } var mergedRanges = new List <IPRange>(); var rangesToMergeSorted = rangesToMerge.Ranges.OrderBy(o => o.Minimum).ThenBy(y => y.Maximum).ToList(); IPRange rangeA = rangesToMergeSorted[0].Copy(); IPRange rangeB = new IPRange(); bool addA = false; bool addB = false; for (int i = 1; i < rangesToMergeSorted.Count; i++) { rangeB = rangesToMergeSorted[i]; if (rangeB.Minimum > rangeA.Maximum) { mergedRanges.Add(rangeA.Copy()); rangeA = rangeB.Copy(); addB = true; addA = false; } else { if (rangeB.Maximum > rangeA.Maximum) { rangeA.Maximum = rangeB.Maximum; } addA = true; addB = false; } } if (addA) { mergedRanges.Add(rangeA); } if (addB) { mergedRanges.Add(rangeB); } return(new IPRanges(mergedRanges)); }
public IPRanges(IPRange range) { Ranges.Add(range); }