Форум программистов, компьютерный форум, киберфорум
C# для начинающих
Войти
Регистрация
Восстановить пароль
Карта форума Темы раздела Блоги Сообщество Поиск Заказать работу  
 
 
Рейтинг 4.94/48: Рейтинг темы: голосов - 48, средняя оценка - 4.94
19 / 19 / 2
Регистрация: 27.09.2011
Сообщений: 155
1

Перебор диапазона IP адресов

22.02.2013, 08:39. Показов 9835. Ответов 23
Метки нет (Все метки)

Author24 — интернет-сервис помощи студентам
В общем вроде бы тривиальная задача, получить список IP-адресов из заданного диапазона. Но решить её никак не получается. Перерыл весь интернет, ни одного полностью рабочего способа не нашёл. Была мысль, что если представить ip в побитовом варианте ( 1.1.1.1 = 00000001 00000001 00000001 00000001) и увеличивать на одно значение, а потом полученные значения блоками конвертировать в int (00000011 00000011 00000011 00000011 = 3.3.3.3).
Но реализовать подобное на C# у меня не получается, т.к. не нашёл типа данных, который хранил бы значения в таком виде (00000011000000110000001100000011), да и что-то это на шизофрению очень смахивает. Не подскажете какие есть ещё варианты? а то я вторую ночь не спал уже(((
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
22.02.2013, 08:39
Ответы с готовыми решениями:

Конвертация IP диапазона в список адресов
Собственно задача в заголовке. Суть: есть IP диапазон (1.2.3.4-5.6.7.8 или CIDR (192.168.1.0/8))....

Сканирование диапазона адресов
Здравствуйте никак не получается просканировать диапазон ip - адресов по порту 7000. Может есть у...

Перебор IP адресов
Всем привет, подскажите как сгенерировать список IP адресов к примеру от 192.168.0.0 до 192.170.0.0

Перебор IP адресов между двумя адресами
Привет. Не подскажете, как написать перебор IP адресов между двумя адресами. На входе числа...

23
338 / 327 / 154
Регистрация: 29.10.2012
Сообщений: 949
22.02.2013, 09:23 2
Может с точки зрения производительности можно решить по другому, а так можно использовать:
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
            //первый адрес диапазона
            long a1 = 192, b1 = 168, c1 = 1, d1 = 253;
 
            //последний адрес диапазона
            long a2 = 192, b2 = 168, c2 = 2, d2 = 8;
 
            //Считаем начальный адрес
            long curentIP = a1 * 256 * 256 * 256 + b1 * 256 * 256 + c1 * 256 + d1;
            //Считаем последний адрес
            long lastIP = a2 * 256 * 256 * 256 + b2 * 256 * 256 + c2 * 256 + d2;
 
            //Считаем количество адресов в данном диапазоне
            long kol = lastIP - curentIP;
 
            //Если диапазон задан в обратной последовательности то выходим
            if (kol < 0) return;
 
            //Создаем массив для записи в него адресов:
            int[,] diapazon = new int[kol+1, 4];
 
            for (long i = 0; i <= kol; i++)
            {
                long ost;
                long a =curentIP / (256 * 256 * 256);
                ost = curentIP % (256 * 256 * 256);
 
                long b = ost / (256 * 256);
                ost = curentIP % (256 * 256);
 
                long c = ost / (256);
                long d = curentIP % (256);
 
                curentIP++;
 
                diapazon[i, 0] = (int)a;
                diapazon[i, 1] = (int)b;
                diapazon[i, 2] = (int)c;
                diapazon[i, 3] = (int)d;
                Console.WriteLine("{0}.{1}.{2}.{3}", diapazon[i, 0], diapazon[i, 1], diapazon[i, 2], diapazon[i, 3]);
 
            }
            Console.ReadLine();
1
713 / 680 / 126
Регистрация: 30.03.2012
Сообщений: 1,124
22.02.2013, 09:41 3
число из 4 байт хммм... инт, нэ?
ну без переполнения лонг
C#
1
2
3
4
long firstIP = (long)(Math.Pow(256, 3) * 127 + Math.Pow(256, 2) * 0 + Math.Pow(256, 1) * 14 + 10); //от 127.0.0.10
            long lastIP= (long)(Math.Pow(256, 3) * 127 + Math.Pow(256, 2) * 1 + Math.Pow(256, 1) * 18 + 256); //до 127.1.18.255
            for (long i = firstIP; i < lastIP; i++)
                Console.WriteLine((IPAddress.Parse(string.Join(".", BitConverter.GetBytes(i).Take(4).Reverse()))));
1
19 / 19 / 2
Регистрация: 27.09.2011
Сообщений: 155
22.02.2013, 10:14  [ТС] 4
C#
1
long firstIP = (long)(Math.Pow(256, 3) * 127 + Math.Pow(256, 2) * 0 + Math.Pow(256, 1) * 14 + 10); //от 127.0.0.10
вот здесь не понятно Math.Pow(256, 1) * 14 почему 14, если в IP 0 . я так понимаю это для 127.0.14.10?
0
713 / 680 / 126
Регистрация: 30.03.2012
Сообщений: 1,124
22.02.2013, 10:31 5
да, ошибся когда комментарий писал, действительно от 14
0
19 / 19 / 2
Регистрация: 27.09.2011
Сообщений: 155
22.02.2013, 10:36  [ТС] 6
тогда всё впорядке, вроде бы работает. Вынес в отдельную функцию, может пригодится кому:
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
private List<IPAddress> GetIPList(IPAddress ipFrom, IPAddress ipTo)
        {
            List<IPAddress> ipList = new List<IPAddress>();
            String[] arrayFrom = ipFrom.ToString().Split(new Char[]{ '.' });
            String[] arrayTo = ipTo.ToString().Split(new Char[] { '.' });
 
            long firstIP = (long)(Math.Pow(256, 3) * Convert.ToInt32(arrayFrom[0]) + Math.Pow(256, 2) * Convert.ToInt32(arrayFrom[1]) + Math.Pow(256, 1) * Convert.ToInt32(arrayFrom[2]) + Convert.ToInt32(arrayFrom[3]));
            long lastIP = (long)(Math.Pow(256, 3) * Convert.ToInt32(arrayTo[0]) + Math.Pow(256, 2) * Convert.ToInt32(arrayTo[1]) + Math.Pow(256, 1) * Convert.ToInt32(arrayTo[2]) + (Convert.ToInt32(arrayTo[3])+1));
 
            for (long i = firstIP; i < lastIP; i++)
                ipList.Add(IPAddress.Parse(string.Join(".", BitConverter.GetBytes(i).Take(4).Reverse())));
            return ipList;
        }
0
Темная сторона .Net
592 / 489 / 39
Регистрация: 21.07.2012
Сообщений: 1,668
22.02.2013, 13:19 7
INF1NUM, а почему через обычный тип byte не решили?
Хотите именно через бинарное представление?
0
19 / 19 / 2
Регистрация: 27.09.2011
Сообщений: 155
22.02.2013, 19:53  [ТС] 8
Noob.net, потому что я нуб =) как получилось, так и решил))))
0
Master of Orion
Эксперт .NET
6098 / 4954 / 905
Регистрация: 10.07.2011
Сообщений: 14,522
Записей в блоге: 5
22.02.2013, 22:28 9
и вместо
C#
1
Math.Pow(256, 3)
лучше написать
C#
1
1 >> 3 * 8
0
773 / 553 / 80
Регистрация: 03.07.2011
Сообщений: 1,020
23.02.2013, 00:16 10
Psilon, Тогда уж лучше просто написать
C#
1
 0
результат все ровно один и тот же
0
Master of Orion
Эксперт .NET
6098 / 4954 / 905
Регистрация: 10.07.2011
Сообщений: 14,522
Записей в блоге: 5
23.02.2013, 00:30 11
Vitall, хм?
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
using System;
 
namespace ConsoleApplication30
{
    class Program
    {
        static void Main()
        {
            Console.WriteLine("Math.Pow = {0}", Math.Pow(256,3));
            Console.WriteLine("SHL = {0}", 1 << 24);
            Console.WriteLine("Zero = {0}", 0);
            Console.ReadKey();
        }
    }
}
http://ideone.com/JJQEFX
0
773 / 553 / 80
Регистрация: 03.07.2011
Сообщений: 1,020
23.02.2013, 00:46 12
гммм

но тем немение

C#
1
2
3
4
  Console.WriteLine("Math.Pow = {0}", Math.Pow(256, 3));
        Console.WriteLine("SHL = {0}",1 >> 3 * 8);
        Console.WriteLine("Zero = {0}", 0);
        Console.ReadKey();
0
Master of Orion
Эксперт .NET
6098 / 4954 / 905
Регистрация: 10.07.2011
Сообщений: 14,522
Записей в блоге: 5
23.02.2013, 00:53 13
Vitall, ну да, сдвиг надо в правильную сторону делать, зачем элементарную описку раздуваете?
0
773 / 553 / 80
Регистрация: 03.07.2011
Сообщений: 1,020
23.02.2013, 01:02 14
По мне так вообще лучше сразу написать число готовое ,чо людей путать
0
Master of Orion
Эксперт .NET
6098 / 4954 / 905
Регистрация: 10.07.2011
Сообщений: 14,522
Записей в блоге: 5
23.02.2013, 01:14 15
Vitall, ну может и стоило бы. Что-то вроде
C#
1
2
3
4
const int
...
 
var result = ip.FirstTetrad * FirstTetradMultipler + ip.SecondTetrad * SecondTetradMultipler + ...
но не уверен, что так понятней.
0
Эксперт .NET
17685 / 12871 / 3365
Регистрация: 17.09.2011
Сообщений: 21,136
23.02.2013, 13:49 16
Цитата Сообщение от INF1NUM Посмотреть сообщение
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
private List<IPAddress> GetIPList(IPAddress ipFrom, IPAddress ipTo)
        {
            List<IPAddress> ipList = new List<IPAddress>();
            String[] arrayFrom = ipFrom.ToString().Split(new Char[]{ '.' });
            String[] arrayTo = ipTo.ToString().Split(new Char[] { '.' });
 
            long firstIP = (long)(Math.Pow(256, 3) * Convert.ToInt32(arrayFrom[0]) + Math.Pow(256, 2) * Convert.ToInt32(arrayFrom[1]) + Math.Pow(256, 1) * Convert.ToInt32(arrayFrom[2]) + Convert.ToInt32(arrayFrom[3]));
            long lastIP = (long)(Math.Pow(256, 3) * Convert.ToInt32(arrayTo[0]) + Math.Pow(256, 2) * Convert.ToInt32(arrayTo[1]) + Math.Pow(256, 1) * Convert.ToInt32(arrayTo[2]) + (Convert.ToInt32(arrayTo[3])+1));
 
            for (long i = firstIP; i < lastIP; i++)
                ipList.Add(IPAddress.Parse(string.Join(".", BitConverter.GetBytes(i).Take(4).Reverse())));
            return ipList;
        }
Мать моя женщина, это же сколько строк и массивов плодиться зря будет?

Вот метод, использующий один-единственный массив.
Если конечный адрес меньше начального, то метод пойдет "по кругу", пока не дойдет до начального.
Работает так же с IPv6.
C#
1
2
3
4
5
6
7
8
9
10
static IEnumerable<IPAddress> EnumerateIpRange(IPAddress from, IPAddress to)
{
    var buffer = from.GetAddressBytes();
    while (!from.Equals(to))
    {       
        yield return from = new IPAddress(buffer);
        int i = buffer.Length - 1;
        while (i >= 0 && ++buffer[i] == 0) i--;
    }
}
1
Master of Orion
Эксперт .NET
6098 / 4954 / 905
Регистрация: 10.07.2011
Сообщений: 14,522
Записей в блоге: 5
23.02.2013, 13:54 17
Только не забываем, что from - ключевое слово )
0
Эксперт .NET
17685 / 12871 / 3365
Регистрация: 17.09.2011
Сообщений: 21,136
23.02.2013, 13:55 18
Цитата Сообщение от Psilon Посмотреть сообщение
from - ключевое слово
Если используется в запросе LINQ.
А так - не ключевое.

Не верьте местной подсветке!
0
Master of Orion
Эксперт .NET
6098 / 4954 / 905
Регистрация: 10.07.2011
Сообщений: 14,522
Записей в блоге: 5
23.02.2013, 13:55 19
и логику вот этого объясните пожалуйста
C#
1
while (i >= 0 && ++buffer[i] == 0) i--;
очень интересно)
Если используется в запросе LINQ.
А так - не ключевое.
любопытно, не знал)
0
Эксперт .NET
17685 / 12871 / 3365
Регистрация: 17.09.2011
Сообщений: 21,136
23.02.2013, 13:59 20
Ой, в первый вариант закрался досадный баг: если from == to, то не возвращает ничего
Исправленный вариант:
C#
1
2
3
4
5
6
7
8
9
10
static IEnumerable<IPAddress> EnumerateIpRange(IPAddress from, IPAddress to)
{
    var buffer = from.GetAddressBytes();
    do
    {
        yield return from = new IPAddress(buffer);
        int i = buffer.Length - 1;
        while (i >= 0 && ++buffer[i] == 0) i--;
    } while (!from.Equals(to));
}
Цитата Сообщение от Psilon Посмотреть сообщение
логику вот этого объясните пожалуйста
C#
1
while (i >= 0 && ++buffer[i] == 0) i--;
Это у меня таким хитрым образом сбрасываются на нули заполненные октеты
Типа buffer = { 128, 255, 255, 255 } => { 129, 0, 0, 0 }
Возможно, сделано через одно место - долго не раздумывал.
0
23.02.2013, 13:59
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
23.02.2013, 13:59
Помогаю со студенческими работами здесь

Перебор IP адресов между двумя адресами
Привет. Не подскажете, как написать перебор IP адресов между двумя адресами. На входе числа...

Реализовать перебор всех возможных IP-адресов (С++)
Реализовать перебор всех возможных IP-адресов, начиная с 0.0.0.0, заканчивая 255.255.255.0. (проще...

Поиск диапазона адресов
Есть строка, определяющая &quot;серость&quot; IP адреса: if echo &quot;$IP&quot; | grep -qE...

Блокировка диапазона ip адресов
Мои сервера часто досят, их ip я знаю Теперь я немогу найти программу которая может запретить...


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

Или воспользуйтесь поиском по форуму:
20
Ответ Создать тему
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2024, CyberForum.ru