Список IP в диапазон

xawer

Client
Регистрация
06.06.2013
Сообщения
11
Благодарностей
5
Баллы
3
Всем привет! Есть список IP около 5млн
197.108.177.11
197.108.177.10
197.108.177.9
197.108.177.8
197.108.177.7
197.108.177.6

197.108.177.4
197.108.177.3
197.108.177.2
197.108.177.1
197.108.177.0

197.108.176.254
197.108.176.253
197.108.176.252
197.108.176.251
Т.е. в основном идут подряд, но некоторые IP убраны. Возможно ли как-то этот список перевести в диапазоны? Задача сократить громоздкий список.
Или как вариант можно ли как-то вычленить из диапазона IP не нужные IP разложив диапазон.
Получается нужно вначале определить в какой диапазон входит IP, а потом убрать его с диапазона
Пример:
Из 41.116.0.0 - 41.116.255.255 убрать 41.116.111.10 получится два диапазона 41.116.0.0-41.116.111.9 и 41.116.111.11-41.116.255.255
Но это походу сложнее, т.к. после каждого вычисления еще и сам список диапазонов будет меняться. Поэтому склонен к первому решению. Нашел тут тему как разложить диапазоны на ip, а как их обратно с убранными не нужными ip собрать в диапазоны не получается. Может кто подскажет куда копать?
 

n0n3mi1y

Client
Регистрация
08.03.2017
Сообщения
1 128
Благодарностей
486
Баллы
83
Задачка интересная, спросил у chatgpt.

Ваши исходные данные состоят из последовательных IP-адресов с некоторыми пропущенными адресами. Если вы хотите перевести список в диапазоны, вы должны найти последовательные блоки IP-адресов и представить их в виде диапазонов. Для этой задачи можно использовать следующий алгоритм:
  1. Преобразуйте каждый IP-адрес в целое число.
  2. Отсортируйте список IP-адресов.
  3. Найдите последовательные блоки IP-адресов.
  4. Представьте каждый блок в виде диапазона.
После получения диапазонов, чтобы "убрать" определенный IP-адрес из диапазона, вам нужно разбить этот диапазон на два поддиапазона, исключая указанный IP-адрес.
C#:
using System;
using System.Linq;
using System.Collections.Generic;

public class IpRangeTool
{
    private static uint IpToInt(string ip)
    {
        return ip.Split('.')
                 .Select(uint.Parse)
                 .Aggregate((a, b) => a * 256 + b);
    }

    private static string IntToIp(uint value)
    {
        return string.Join(".", BitConverter.GetBytes(value).Reverse());
    }

    public static List<Tuple<string, string>> FindRanges(List<string> ips)
    {
        var sortedIps = ips.Select(IpToInt).OrderBy(x => x).ToList();
        var ranges = new List<Tuple<uint, uint>>();
        uint start = sortedIps[0];
        
        for (int i = 1; i < sortedIps.Count; i++)
        {
            if (sortedIps[i] != sortedIps[i - 1] + 1)
            {
                ranges.Add(new Tuple<uint, uint>(start, sortedIps[i - 1]));
                start = sortedIps[i];
            }
        }
        ranges.Add(new Tuple<uint, uint>(start, sortedIps.Last()));
        return ranges.Select(r => new Tuple<string, string>(IntToIp(r.Item1), IntToIp(r.Item2))).ToList();
    }

    public static List<Tuple<string, string>> RemoveIpFromRange(Tuple<string, string> range, string ip)
    {
        uint ipInt = IpToInt(ip);
        uint start = IpToInt(range.Item1);
        uint end = IpToInt(range.Item2);
        
        if (start == ipInt)
        {
            return new List<Tuple<string, string>> { new Tuple<string, string>(IntToIp(start + 1), range.Item2) };
        }
        else if (end == ipInt)
        {
            return new List<Tuple<string, string>> { new Tuple<string, string>(range.Item1, IntToIp(end - 1)) };
        }
        else
        {
            return new List<Tuple<string, string>>
            {
                new Tuple<string, string>(range.Item1, IntToIp(ipInt - 1)),
                new Tuple<string, string>(IntToIp(ipInt + 1), range.Item2)
            };
        }
    }
}

// Пример использования
public class Program
{
    static void Main()
    {
        var ips = new List<string>
        {
            "197.108.177.11", "197.108.177.10", "197.108.177.9",
            // ... другие IP адреса
        };

        var ranges = IpRangeTool.FindRanges(ips);
        foreach (var range in ranges)
        {
            Console.WriteLine($"{range.Item1} - {range.Item2}");
        }

        string ipToRemove = "41.116.111.10";
        var newRanges = IpRangeTool.RemoveIpFromRange(new Tuple<string, string>("41.116.0.0", "41.116.255.255"), ipToRemove);
        foreach (var range in newRanges)
        {
            Console.WriteLine($"{range.Item1} - {range.Item2}");
        }
    }
}

А теперь эту реализацию добавим в постер.

Всё из метода Main мы помещаем в кубик выполнения кода C#. Класс для преобразования списка IP в диапазоны мы помещаем в "Директивы using и общий код".
При помещение не забываем, что методы по типу Console.WriteLine необходимо трансформировать в project.SendInfoToLog (или иной).

Конечный результат выполнения кода:
110471


Проект прикреплён. Вроде бы, результат именно такой, какой и нужен был.


P.S. Chatpgpt предупредил о том, что могут быть беды при обработке 5 000 000 адресов, но как мне кажется - такого не будет. 5 000 000 строк вряд ли сильно нагрузят систему, но лучше протестировать.
 

Вложения

  • Спасибо
Реакции: xawer

xawer

Client
Регистрация
06.06.2013
Сообщения
11
Благодарностей
5
Баллы
3
Задачка интересная, спросил у chatgpt.



C#:
using System;
using System.Linq;
using System.Collections.Generic;

public class IpRangeTool
{
    private static uint IpToInt(string ip)
    {
        return ip.Split('.')
                 .Select(uint.Parse)
                 .Aggregate((a, b) => a * 256 + b);
    }

    private static string IntToIp(uint value)
    {
        return string.Join(".", BitConverter.GetBytes(value).Reverse());
    }

    public static List<Tuple<string, string>> FindRanges(List<string> ips)
    {
        var sortedIps = ips.Select(IpToInt).OrderBy(x => x).ToList();
        var ranges = new List<Tuple<uint, uint>>();
        uint start = sortedIps[0];
      
        for (int i = 1; i < sortedIps.Count; i++)
        {
            if (sortedIps[i] != sortedIps[i - 1] + 1)
            {
                ranges.Add(new Tuple<uint, uint>(start, sortedIps[i - 1]));
                start = sortedIps[i];
            }
        }
        ranges.Add(new Tuple<uint, uint>(start, sortedIps.Last()));
        return ranges.Select(r => new Tuple<string, string>(IntToIp(r.Item1), IntToIp(r.Item2))).ToList();
    }

    public static List<Tuple<string, string>> RemoveIpFromRange(Tuple<string, string> range, string ip)
    {
        uint ipInt = IpToInt(ip);
        uint start = IpToInt(range.Item1);
        uint end = IpToInt(range.Item2);
      
        if (start == ipInt)
        {
            return new List<Tuple<string, string>> { new Tuple<string, string>(IntToIp(start + 1), range.Item2) };
        }
        else if (end == ipInt)
        {
            return new List<Tuple<string, string>> { new Tuple<string, string>(range.Item1, IntToIp(end - 1)) };
        }
        else
        {
            return new List<Tuple<string, string>>
            {
                new Tuple<string, string>(range.Item1, IntToIp(ipInt - 1)),
                new Tuple<string, string>(IntToIp(ipInt + 1), range.Item2)
            };
        }
    }
}

// Пример использования
public class Program
{
    static void Main()
    {
        var ips = new List<string>
        {
            "197.108.177.11", "197.108.177.10", "197.108.177.9",
            // ... другие IP адреса
        };

        var ranges = IpRangeTool.FindRanges(ips);
        foreach (var range in ranges)
        {
            Console.WriteLine($"{range.Item1} - {range.Item2}");
        }

        string ipToRemove = "41.116.111.10";
        var newRanges = IpRangeTool.RemoveIpFromRange(new Tuple<string, string>("41.116.0.0", "41.116.255.255"), ipToRemove);
        foreach (var range in newRanges)
        {
            Console.WriteLine($"{range.Item1} - {range.Item2}");
        }
    }
}

А теперь эту реализацию добавим в постер.

Всё из метода Main мы помещаем в кубик выполнения кода C#. Класс для преобразования списка IP в диапазоны мы помещаем в "Директивы using и общий код".
При помещение не забываем, что методы по типу Console.WriteLine необходимо трансформировать в project.SendInfoToLog (или иной).

Конечный результат выполнения кода:
Посмотреть вложение 110471

Проект прикреплён. Вроде бы, результат именно такой, какой и нужен был.


P.S. Chatpgpt предупредил о том, что могут быть беды при обработке 5 000 000 адресов, но как мне кажется - такого не будет. 5 000 000 строк вряд ли сильно нагрузят систему, но лучше протестировать.
Спасибо вам большое, что откликнулись! У меня версия ZP 7.1.4.0 если есть ли возможность понизить версию и время свободное, скиньте пожалуйста. Сейчас попробую сделать что-нибудь с кодом, который вы скинули, C# правда не знаю, но попробую) В компиляторе вроде работает.
 
Последнее редактирование:

n0n3mi1y

Client
Регистрация
08.03.2017
Сообщения
1 128
Благодарностей
486
Баллы
83
Спасибо вам большое, что откликнулись! У меня версия ZP 7.1.4.0 если есть ли возможность понизить версию и время свободное, скиньте пожалуйста. Сейчас попробую сделать что-нибудь с кодом, который вы скинули, C# правда не знаю, но попробую) В компиляторе вроде работает.
До такой низкой версии у меня не понижает.
 

n0n3mi1y

Client
Регистрация
08.03.2017
Сообщения
1 128
Благодарностей
486
Баллы
83
Содержимое общего кода:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading;
using System.IO;
using System.Text.RegularExpressions;
using ZennoLab.CommandCenter;
using ZennoLab.InterfacesLibrary;
using ZennoLab.InterfacesLibrary.ProjectModel;
using ZennoLab.InterfacesLibrary.ProjectModel.Collections;
using ZennoLab.InterfacesLibrary.ProjectModel.Enums;
using ZennoLab.Macros;
using Global.ZennoExtensions;
using ZennoLab.Emulation;
using ZennoLab.CommandCenter.TouchEvents;
using ZennoLab.CommandCenter.FullEmulation;
using ZennoLab.InterfacesLibrary.Enums;

namespace ZennoLab.OwnCode
{
    /// <summary>
    /// A simple class of the common code
    /// </summary>
    public class CommonCode
    {
        /// <summary>
        /// Lock this object to mark part of code for single thread execution
        /// </summary>
        public static object SyncObject = new object();

        // Insert your code here
    }
    
    public class IpRangeTool
{
    private static uint IpToInt(string ip)
    {
        return ip.Split('.')
                 .Select(uint.Parse)
                 .Aggregate((a, b) => a * 256 + b);
    }

    private static string IntToIp(uint value)
    {
        return string.Join(".", BitConverter.GetBytes(value).Reverse());
    }

    public static List<Tuple<string, string>> FindRanges(List<string> ips)
    {
        var sortedIps = ips.Select(IpToInt).OrderBy(x => x).ToList();
        var ranges = new List<Tuple<uint, uint>>();
        uint start = sortedIps[0];
        
        for (int i = 1; i < sortedIps.Count; i++)
        {
            if (sortedIps[i] != sortedIps[i - 1] + 1)
            {
                ranges.Add(new Tuple<uint, uint>(start, sortedIps[i - 1]));
                start = sortedIps[i];
            }
        }
        ranges.Add(new Tuple<uint, uint>(start, sortedIps.Last()));
        return ranges.Select(r => new Tuple<string, string>(IntToIp(r.Item1), IntToIp(r.Item2))).ToList();
    }

    public static List<Tuple<string, string>> RemoveIpFromRange(Tuple<string, string> range, string ip)
    {
        uint ipInt = IpToInt(ip);
        uint start = IpToInt(range.Item1);
        uint end = IpToInt(range.Item2);
        
        if (start == ipInt)
        {
            return new List<Tuple<string, string>> { new Tuple<string, string>(IntToIp(start + 1), range.Item2) };
        }
        else if (end == ipInt)
        {
            return new List<Tuple<string, string>> { new Tuple<string, string>(range.Item1, IntToIp(end - 1)) };
        }
        else
        {
            return new List<Tuple<string, string>>
            {
                new Tuple<string, string>(range.Item1, IntToIp(ipInt - 1)),
                new Tuple<string, string>(IntToIp(ipInt + 1), range.Item2)
            };
        }
    }
}
}



Содержимое кубика:
var ips = project.Lists["ipRange"].ToList();
var ranges = IpRangeTool.FindRanges(ips);
foreach (var range in ranges)
{
    project.SendInfoToLog($"{range.Item1} - {range.Item2}");
}

string ipToRemove = "41.116.111.10";
var newRanges = IpRangeTool.RemoveIpFromRange(new Tuple<string, string>("41.116.0.0", "41.116.255.255"), ipToRemove);
foreach (var range in newRanges)
{
    project.SendInfoToLog($"{range.Item1} - {range.Item2}");
}


Структура
110488



Имя списка в zennoPoster - ipRange.
 
  • Спасибо
Реакции: xawer

xawer

Client
Регистрация
06.06.2013
Сообщения
11
Благодарностей
5
Баллы
3
Содержимое общего кода:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading;
using System.IO;
using System.Text.RegularExpressions;
using ZennoLab.CommandCenter;
using ZennoLab.InterfacesLibrary;
using ZennoLab.InterfacesLibrary.ProjectModel;
using ZennoLab.InterfacesLibrary.ProjectModel.Collections;
using ZennoLab.InterfacesLibrary.ProjectModel.Enums;
using ZennoLab.Macros;
using Global.ZennoExtensions;
using ZennoLab.Emulation;
using ZennoLab.CommandCenter.TouchEvents;
using ZennoLab.CommandCenter.FullEmulation;
using ZennoLab.InterfacesLibrary.Enums;

namespace ZennoLab.OwnCode
{
    /// <summary>
    /// A simple class of the common code
    /// </summary>
    public class CommonCode
    {
        /// <summary>
        /// Lock this object to mark part of code for single thread execution
        /// </summary>
        public static object SyncObject = new object();

        // Insert your code here
    }
   
    public class IpRangeTool
{
    private static uint IpToInt(string ip)
    {
        return ip.Split('.')
                 .Select(uint.Parse)
                 .Aggregate((a, b) => a * 256 + b);
    }

    private static string IntToIp(uint value)
    {
        return string.Join(".", BitConverter.GetBytes(value).Reverse());
    }

    public static List<Tuple<string, string>> FindRanges(List<string> ips)
    {
        var sortedIps = ips.Select(IpToInt).OrderBy(x => x).ToList();
        var ranges = new List<Tuple<uint, uint>>();
        uint start = sortedIps[0];
       
        for (int i = 1; i < sortedIps.Count; i++)
        {
            if (sortedIps[i] != sortedIps[i - 1] + 1)
            {
                ranges.Add(new Tuple<uint, uint>(start, sortedIps[i - 1]));
                start = sortedIps[i];
            }
        }
        ranges.Add(new Tuple<uint, uint>(start, sortedIps.Last()));
        return ranges.Select(r => new Tuple<string, string>(IntToIp(r.Item1), IntToIp(r.Item2))).ToList();
    }

    public static List<Tuple<string, string>> RemoveIpFromRange(Tuple<string, string> range, string ip)
    {
        uint ipInt = IpToInt(ip);
        uint start = IpToInt(range.Item1);
        uint end = IpToInt(range.Item2);
       
        if (start == ipInt)
        {
            return new List<Tuple<string, string>> { new Tuple<string, string>(IntToIp(start + 1), range.Item2) };
        }
        else if (end == ipInt)
        {
            return new List<Tuple<string, string>> { new Tuple<string, string>(range.Item1, IntToIp(end - 1)) };
        }
        else
        {
            return new List<Tuple<string, string>>
            {
                new Tuple<string, string>(range.Item1, IntToIp(ipInt - 1)),
                new Tuple<string, string>(IntToIp(ipInt + 1), range.Item2)
            };
        }
    }
}
}



Содержимое кубика:
var ips = project.Lists["ipRange"].ToList();
var ranges = IpRangeTool.FindRanges(ips);
foreach (var range in ranges)
{
    project.SendInfoToLog($"{range.Item1} - {range.Item2}");
}

string ipToRemove = "41.116.111.10";
var newRanges = IpRangeTool.RemoveIpFromRange(new Tuple<string, string>("41.116.0.0", "41.116.255.255"), ipToRemove);
foreach (var range in newRanges)
{
    project.SendInfoToLog($"{range.Item1} - {range.Item2}");
}


Структура
Посмотреть вложение 110488


Имя списка в zennoPoster - ipRange.
Класс, спасибо большое! Буду тестировать
 

Кто просматривает тему: (Всего: 1, Пользователи: 0, Гости: 1)