Форум программистов, компьютерный форум, киберфорум
C# для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.55/11: Рейтинг темы: голосов - 11, средняя оценка - 4.55
11 / 11 / 3
Регистрация: 16.10.2012
Сообщений: 139

Алгоритм для вычитания одного диапазона IP из другого

06.08.2014, 19:33. Показов 2299. Ответов 4
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Есть два файла с диапазонами IP адресов вида:
2.60.0.0-2.60.2.255
2.60.4.0-2.60.8.255
2.60.10.0-2.60.10.255
2.60.13.0-2.60.13.255

Нужно сформировать третий диапазон. Из первого файла original.txt исключить диапазоны из файла subtract.txt
Я уже голову себе сломал. Ничего умнее, чем решать "в лоб" придумать не могу. А это - найти все IP из диапазонов первого файла, найти все IP из диапазонов второго файла, выкинуть лишнее. А потом снова как-то привести к диапазонам

Ещё нашёл такую штуку:
http://ipnetwork.codeplex.com/

Работает так:
C#
1
2
3
4
5
6
7
8
9
IPNetwork ipnetwork = IPNetwork.Parse("192.168.168.100/24");
 
Console.WriteLine("Network : {0}", ipnetwork.Network);
Console.WriteLine("Netmask : {0}", ipnetwork.Netmask);
Console.WriteLine("Broadcast : {0}", ipnetwork.Broadcast);
Console.WriteLine("FirstUsable : {0}", ipnetwork.FirstUsable);
Console.WriteLine("LastUsable : {0}", ipnetwork.LastUsable);
Console.WriteLine("Usable : {0}", ipnetwork.Usable);
Console.WriteLine("Cidr : {0}", ipnetwork.Cidr);
И есть у этого класса разные прикольные методы. Но ничего подходящего я найти всё равно не смог. Впрочем у меня диапазоны для "вычитания" и в этом формате. Файл - subtractRanges.txt


Посоветуйте, что делать с этой проблемой.
Вложения
Тип файла: zip ranges.zip (60.6 Кб, 5 просмотров)
Тип файла: txt subtractRanges.txt (7.1 Кб, 6 просмотров)
0
Лучшие ответы (1)
IT_Exp
Эксперт
34794 / 4073 / 2104
Регистрация: 17.06.2006
Сообщений: 32,602
Блог
06.08.2014, 19:33
Ответы с готовыми решениями:

Как корректно записать результат вычитания одного значения функции Now из другого Now
делаю типа макроса для учета времени работы над проектами. Делаю так: Пускаю макрос Старт и он записывает в некоторую ячейку данные...

Макрос для копирования данных из диапазона таблицы одного листа и вставка в диапазон таблицы другого листа
Добрый день! Прошу подсказать как написать макрос, чтобы он искал ячейку со значением "февраль" Лист2 и копировал диапазон...

Ускорить алгоритм удаления одного списка из другого
Здравствуйте. Есть два списка : один на 181093 строк другой на 80000. Нужно удалить один список из другого. Моя реализация: ...

4
 Аватар для ViterAlex
8951 / 4863 / 1886
Регистрация: 11.02.2013
Сообщений: 10,246
07.08.2014, 13:28
IP-адреса это просто числа, просто записанные в определённой форме. Задача сводится к определению вхождения одного числового диапазона в другой.
Пусть имеются два диапазона a — b и c — d, заданные так, что a>b и c>d. Возможны 4 варианта из пересечений:
  1. a>c & b<c & b>d — верхняя граница второго диапазона попадает внутрь первого
  2. a<c & a>d & b<d — нижняя граница второго диапазона попадает внутрь первого
  3. a>c & b<d — весь второй диапазон попадает внутрь первого
  4. a<c & b>d — весь первый диапазон попадает внутрь второго
Соответственно, возможны 4 варианта разбиения на результирующие диапазоны:
  1. a — c, b — d
  2. c — a, d — b
  3. a — c, d — b
  4. c — a, d — b

Добавлено через 1 час 46 минут
Примерно так может выглядеть реализация (без обработки исключений и пограничных условий):
Программа
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
using System;
using System.IO;
using System.Text;
namespace ConsoleApplication1 {
    class Program {
        static void Main(string[] args) {
            string[] orig = File.ReadAllLines(@"..\..\original.txt", Encoding.Default);
            string[] subtract = File.ReadAllLines(@"..\..\subtract.txt", Encoding.Default);
            StreamWriter sw = new StreamWriter(@"..\..\result.txt");
            IPRange ipOrig, ipSub;
            foreach (string origItem in orig) {
                ipOrig = IPRange.Parse(origItem);
                foreach (string subtractItem in subtract) {
                    ipSub = IPRange.Parse(subtractItem);
                    IPRange[] res = ipOrig.Exclude(ipSub);
                    if (res.Length > 0) {
                        sw.WriteLine(res[0].ToString());
                        sw.WriteLine(res[1].ToString());
                        Console.WriteLine(res[0].ToString());
                        Console.WriteLine(res[1].ToString());
                    }
                }
            }           
            sw.Close();
            Console.Read();
        }
    }
}

Класс IPRange
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
using System;
using System.Net;
 
namespace ConsoleApplication1 {
    public class IPRange {
        public readonly IPAddress LowerBound;
        public readonly IPAddress UpperBound;
 
        public IPRange(IPAddress lowerBound, IPAddress upperBound) {
            if (lowerBound.ToInteger() > upperBound.ToInteger())
                throw new ArgumentException("Нижний адрес должен быть меньше верхнего.");
            this.LowerBound = lowerBound;
            this.UpperBound = upperBound;
        }
 
        public bool Contains(IPAddress address) {
            return (address.ToInteger() < UpperBound.ToInteger()) && (address.ToInteger() > LowerBound.ToInteger());
        }
 
        /// <summary>
        /// Исключение адресов, принадлежащих сразу двум диапазонам
        /// </summary>
        /// <param name="range">Заданный диапазон адресов</param>
        /// <returns>Массив диапазонов, включающих адреса, принадлежащие только одному из диапазонов</returns>
        public IPRange[] Exclude(IPRange range) {
            IPRange[] result = new IPRange[0];
            //Верхняя граница заданного диапазона попадает в данный диапазон
            if (this.Contains(range.UpperBound) && range.Contains(this.LowerBound)) {
                Array.Resize<IPRange>(ref result, 2);
                result[0] = new IPRange(range.LowerBound, this.LowerBound);
                result[1] = new IPRange(range.UpperBound, this.UpperBound);
                return result;
            }
            //Нижняя граница заданного диапазона попадает в данный диапазон
            if (this.Contains(range.LowerBound) && range.Contains(this.UpperBound)) {
                Array.Resize<IPRange>(ref result, 2);
                result[0] = new IPRange(this.LowerBound, range.LowerBound);
                result[1] = new IPRange(this.UpperBound, range.UpperBound);
                return result;
            }
            //Весь заданный диапазон попадает внутрь данного диапазона
            if (this.Contains(range.UpperBound) && this.Contains(range.LowerBound)) {
                Array.Resize<IPRange>(ref result, 2);
                result[0] = new IPRange(this.LowerBound, range.LowerBound);
                result[1] = new IPRange(range.UpperBound, this.UpperBound);
                return result;
            }
            //Весь данный диапазон попадает внутрь заданного диапазона
            if (range.Contains(this.UpperBound) && range.Contains(this.LowerBound)) {
                Array.Resize<IPRange>(ref result, 2);
                result[0] = new IPRange(range.LowerBound, this.LowerBound);
                result[1] = new IPRange(this.UpperBound, range.UpperBound);
                return result;
            }
            return result;
        }
 
        public override string ToString() {
            return string.Format("{0} - {1}", LowerBound.ToString(), UpperBound.ToString());
        }
 
        /// <summary>
        /// Получение диапазона адресов из строковой записи
        /// </summary>
        /// <param name="stringRange">Строковое представление диапазона адресов вида xxx.xxx.xxx.xxx-xxx.xxx.xxx.xxx</param>
        /// <returns>Экземпляр класса IPRange</returns>
        public static IPRange Parse(string stringRange) {
            IPAddress ipL, ipU;
            string[] addresses = stringRange.Split('-');
            ipL = IPAddress.Parse(addresses[0]);
            ipU = IPAddress.Parse(addresses[1]);
            return new IPRange(ipL, ipU);
        }
    }
 
    public static class IPAddressExtension {
        public static int ToInteger(this IPAddress address) {
            byte[] bytes = address.GetAddressBytes();
            return (int)(bytes[0] << 24 | bytes[1] << 16 | bytes[2] << 8 | bytes[3]);
        }
    }
}
1
11 / 11 / 3
Регистрация: 16.10.2012
Сообщений: 139
08.08.2014, 11:35  [ТС]
Цитата Сообщение от ViterAlex Посмотреть сообщение
Примерно так может выглядеть реализация (без обработки исключений и пограничных условий):
Огромное спасибо за реализацию. Правда работает это как-то странно.
Посмотрел на самое начало исходного файла original. В нём есть диапазоны, которые я приводил в первом посте:
2.60.0.0-2.60.2.255
2.60.4.0-2.60.8.255
2.60.10.0-2.60.10.255
2.60.13.0-2.60.13.255

А в subtract их нет. Следовательно, эти диапазоны должны быть в результирующем файле. Но там и тоже нет.
0
 Аватар для ViterAlex
8951 / 4863 / 1886
Регистрация: 11.02.2013
Сообщений: 10,246
08.08.2014, 12:51
Лучший ответ Сообщение было отмечено AlexanderWM как решение

Решение

Цитата Сообщение от AlexanderWM Посмотреть сообщение
работает это как-то странно...
в subtract их нет. Следовательно, эти диапазоны должны быть в результирующем файле
Ну так всего-то делов, флаг добавить:
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
bool excluded;
foreach (string origItem in orig) {
 
    ipOrig = IPRange.Parse(origItem);
    excluded = false;
 
    foreach (string subtractItem in subtract) {
 
        ipSub = IPRange.Parse(subtractItem);
        IPRange[] res = ipOrig.Exclude(ipSub);
        if (res.Length > 0) {
            sw.WriteLine(res[0].ToString());
            sw.WriteLine(res[1].ToString());
            Console.WriteLine(res[0].ToString());
            Console.WriteLine(res[1].ToString());
            excluded = true;
        }
 
    }
 
    if (!excluded) {
        sw.WriteLine(ipOrig.ToString());
        Console.WriteLine(ipOrig.ToString());
    }
 
}
1
11 / 11 / 3
Регистрация: 16.10.2012
Сообщений: 139
08.08.2014, 12:57  [ТС]
Круто! Теперь всё похоже на правду. Спасибо
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
BasicMan
Эксперт
29316 / 5623 / 2384
Регистрация: 17.02.2009
Сообщений: 30,364
Блог
08.08.2014, 12:57
Помогаю со студенческими работами здесь

вычисление остатка от деления суммы чисел одного диапазона на сумму чисел другого
Необходимо записать формулу или функцию для вычисления остатка от деления суммы чисел диапазона А11:Е15 на сумму чисел диапазона A1:E5

Гистограмма, в которой высота столбцов зависит от одного диапазона, а ширина столбцов от другого
Доброго времени суток! Прошу помочь вас, в сложной для меня проблеме. не могу &quot;нарисовать&quot; гистограмму в которой ВЫСОТА столбцов...

Алгоритм Маркова для вычитания двоичных чисел
Доброго времени. Кто нибудь может написать алгоритм маркова для вычитания двоичных чисел? Очень надо, а найти не могу, допереть тоже.

Составить нормальный алгоритм маркова для вычитания в унарной сс
Например, нужно реализовать ||||||||-|||-| подкиньте хотя бы идейки. со сложением разобралась, а вычитание не понимаю.

Заполнение именованного диапазона данными из другого диапазона по условию: код не работает
Заполняю таблицу с данными о пищевой ценности продуктов. Простейший скрипт, ищущий совпадение в одной таблице (вроде БД), и, если...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
5
Ответ Создать тему
Новые блоги и статьи
Thinkpad X220 Tablet — это лучший бюджетный ноутбук для учёбы, точка.
Programma_Boinc 23.12.2025
Рецензия / Мнение/ Перевод Нашел на реддите интересную статью под названием The Thinkpad X220 Tablet is the best budget school laptop period . Ниже её машинный перевод. Thinkpad X220 Tablet —. . .
PhpStorm 2025.3: WSL Terminal всегда стартует в ~
and_y87 14.12.2025
PhpStorm 2025. 3: WSL Terminal всегда стартует в ~ (home), игнорируя директорию проекта Симптом: После обновления до PhpStorm 2025. 3 встроенный терминал WSL открывается в домашней директории. . .
Как объединить две одинаковые БД Access с разными данными
VikBal 11.12.2025
Помогите пожалуйста !! Как объединить 2 одинаковые БД Access с разными данными.
Новый ноутбук
volvo 07.12.2025
Всем привет. По скидке в "черную пятницу" взял себе новый ноутбук Lenovo ThinkBook 16 G7 на Амазоне: Ryzen 5 7533HS 64 Gb DDR5 1Tb NVMe 16" Full HD Display Win11 Pro
Музыка, написанная Искусственным Интеллектом
volvo 04.12.2025
Всем привет. Некоторое время назад меня заинтересовало, что уже умеет ИИ в плане написания музыки для песен, и, собственно, исполнения этих самых песен. Стихов у нас много, уже вышли 4 книги, еще 3. . .
От async/await к виртуальным потокам в Python
IndentationError 23.11.2025
Армин Ронахер поставил под сомнение async/ await. Создатель Flask заявляет: цветные функции - провал, виртуальные потоки - решение. Не threading-динозавры, а новое поколение лёгких потоков. Откат?. . .
Поиск "дружественных имён" СОМ портов
Argus19 22.11.2025
Поиск "дружественных имён" СОМ портов На странице: https:/ / norseev. ru/ 2018/ 01/ 04/ comportlist_windows/ нашёл схожую тему. Там приведён код на С++, который показывает только имена СОМ портов, типа,. . .
Сколько Государство потратило денег на меня, обеспечивая инсулином.
Programma_Boinc 20.11.2025
Сколько Государство потратило денег на меня, обеспечивая инсулином. Вот решила сделать интересный приблизительный подсчет, сколько государство потратило на меня денег на покупку инсулинов. . . .
Ломающие изменения в C#.NStar Alpha
Etyuhibosecyu 20.11.2025
Уже можно не только тестировать, но и пользоваться C#. NStar - писать оконные приложения, содержащие надписи, кнопки, текстовые поля и даже изображения, например, моя игра "Три в ряд" написана на этом. . .
Мысли в слух
kumehtar 18.11.2025
Кстати, совсем недавно имел разговор на тему медитаций с людьми. И обнаружил, что они вообще не понимают что такое медитация и зачем она нужна. Самые базовые вещи. Для них это - когда просто люди. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2025, CyberForum.ru