using System; using System.ComponentModel; using System.Diagnostics; using System.Text; partial class Program { static void Main() { int threads = 20;//с потоками экспериментировать Stopwatch st = Stopwatch.StartNew(); var Ranges = new Ranges();//тут будет словарь string path_for_ranges = @"C:\Users\Alex\Desktop\netnum.txt";//пути заменить на свои string path_for_ip = @"C:\Users\Alex\Desktop\ip.txt";//пути заменить на свои Console.WriteLine("Считываю список ip из файла 'ip.txt'\n"); var iplist = File.ReadAllLines(path_for_ip); Console.WriteLine($"В списке 'ip.txt': {iplist.Count()} строк. Время считывания файла {st.Elapsed}\n"); Task aggregateData = new Task(() => { Console.WriteLine("Считываю список диапазонов из файла 'netnum.txt'\n"); var list = File.ReadAllLines(path_for_ranges); Console.WriteLine($"\nВ списке 'netnum.txt': {list.Count()} строк. Время считывания файла {st.Elapsed}\n"); st.Restart(); Console.WriteLine("Дроблю 'netnum.txt' по первому октету на подсписки и конвертирую диапазоны в числовые значения\n"); list.GroupBy(x => x.Split('.').First()) .AsParallel().WithDegreeOfParallelism(threads).ForAll(x => { Ranges.IpRanges.Add( x.Key, x.Select( w => (new Converter().rangeTolong(w.Split(new[] { " - " }, StringSplitOptions.RemoveEmptyEntries) .Select(y => y.Trim()).ToArray()))).ToList()); }); }); aggregateData.Start(); Console.WriteLine(); while (!aggregateData.IsCompleted) { Thread.Sleep(500); Console.Write('.'); } Console.WriteLine($"\nПолучилось: {Ranges.IpRanges.Count} подсписков, в каждом из которых в среднем по {Ranges.IpRanges.Average(x => x.Value.Count)} строк. Затраченное время: {st.Elapsed}\n"); Console.WriteLine($"\nПриступаю к проверке списка 'ip.txt' в цикле по подспискам 'netnum.txt'"); for (int i = 0; i < 5; i++) { Task check = new Task(() => { Console.WriteLine($"Итерация №: {i + 1}"); Ranges.ranged_ips.Clear(); iplist.AsParallel().WithDegreeOfParallelism(threads).ForAll(ip => { var IP = new IP(ip); if (Ranges.IpRanges.Keys.Contains(IP.octet)) { try { string range = string.Join(" - ", Ranges.IpRanges[IP.octet].Single(x => new Check(IP.long_ip, x).check)); lock (Locker.locker) { Ranges.ranged_ips.Add(new[] { ip, range }); } } catch { } } }); }); st.Restart(); check.Start(); while (!check.IsCompletedSuccessfully) { Thread.Sleep(1000); Console.Write('*'); } Console.WriteLine($"\nНайдено {Ranges.ranged_ips.Count} попаданий некоторых ip в диапазоны. Затраченное время на проверку списка: {st.Elapsed}"); } } } class Converter { public long[] rangeTolong(string[] _diapazon) { return _diapazon.Select(x => ipConvertToLongFormat(x)).ToArray(); } public long ipConvertToLongFormat(string _ip) { return long.Parse(string.Join("", _ip.Split('.').Select(x => $"00{x}".Substring(x.Length - 1)))); } } class IP { public string octet; public long long_ip; public IP(string _ip) { octet = _ip.Split('.').First(); long_ip = new Converter().ipConvertToLongFormat(_ip); } } class Check { public bool check; public Check(long ip, long[] range) { check = ip >= range[0] && ip <= range[1]; } } class Ranges { public Dictionary> IpRanges = new(); public List ranged_ips = new(); } static class Locker { public static object locker = new(); }