Определите дубликаты и перекрывающиеся IP-адреса в новом столбце

У меня есть следующий запрос.

У меня есть этот фрейм данных, который имеет следующие столбцы:

Site IP     Site Name   Instance    Interface Name  Network Add     Interface IP
20.X.X.1    ROUTER1     VPRN1       interface1      20.49.128.0/17  20.49.208.129   
20.X.X.2    ROUTER2     VPRN1       interface2      20.84.34.0/24   20.84.34.3
20.X.X.3    ROUTER3     VPRN1       interface3      20.84.34.0/24   20.84.34.3
20.X.X.4    ROUTER4     VPRN1       interface4      20.85.51.0/23   20.85.51.1
20.X.X.5    ROUTER5     VPRN1       interface5      20.85.52.0/24   20.85.52.1

И мне нужно проверить, является ли какой-либо из адресов IP Дублирующимся или Наложенным , Что касается перекрытия, я имею в виду, например, если у нас есть интерфейс с ip 192.168.1.7/30 и другой с ip 192.168.1.3/29, то 192.168.1.3/29 охватывает 192.168.1.7/30, и они перекрываются. Эта проверка, мне нужно поместить ее в новый столбец под названием Status.

Site IP     Site Name   Instance    Interface Name  Network Add     Interface IP        Status
20.X.X.1    ROUTER1     VPRN1       interface1      20.49.128.0/17  20.49.208.129       OK
20.X.X.2    ROUTER2     VPRN1       interface2      20.84.34.0/24   20.84.34.3          Duplicated
20.X.X.3    ROUTER3     VPRN1       interface3      20.84.34.0/24   20.84.34.3          Duplicated
20.X.X.4    ROUTER4     VPRN1       interface4      20.85.51.0/23   20.85.51.1          Overlapped
20.X.X.5    ROUTER5     VPRN1       interface5      20.85.52.0/24   20.85.52.1          Overlapped

Надеюсь, вы мне поможете. Спасибо большое! Хуан Пабло.

5
задан 28.11.2019, 17:23
1 ответ

ActualizaciГіn

Tras чаты в чате, освещает, что она detecciГіn из дублированных IPs он должен делаться на основании колонны "Интерфейс IP", в то время как хитрые ранги должны быть расположены на основании колонны "Нетворк Адд".

На основании этого я изменил слегка первоначальный ответ, вместо того, чтобы делать один aГ±adido, так как изменения касаются нескольких частей.

Она soluciГіn, что со мной случилось, хотя немного перегруженная объяснения, это в конце концов рубка помогания и очень обще. Я думаю, что оно функционирует во всех случаях. Идея - следующая.

  • Обнаруживать дубликаты в колонне "Интерфейс IP" - просто, так как Панды уже нам дает один mГ©todo dataframe.duplicated() (в конце концов мы это используем)
  • , Обнаруживать solapamiento районов - mГЎs сложно, особенно, если они могут появляться в любой команде, так как algГєn способ нужен сравнивать все со всеми. mГіdulo ipaddress может помогать aquГ - в части, которая определяет, если два ранга, выраженных в CDIR solapan или нет.

Идея для второй cuestiГіn serГ - в как останься:

  1. Извлекать колонну "Нетворк Адд" в список
  2. Упорядочивать список используя одну funciГіn особенные key, что возвратил 0, если два адреса solapan (usarГЎ для этого класс ipaddress.IPv4Network)
  3. Применять itertools.groupby() на этом аккуратном списке, и использовать, чтобы группировать ту же самую funciГіn специальная, с которым мы упорядочиваем колонну. Это crearГЎ группы, в которых meterГЎ все хитрые "Нетворк Адд", хотя tambiГ©n meterГЎ в разведеных группах те, у которых есть повторенные "Нетворк Адд" (которые в действительности не считают в этой проблеме), и tambiГ©n crearГЎ группы с единственным элементом для тех, у которых есть стоимость Гєnicos.
  4. Обрабатывать результат этого groupby(), чтобы создавать список sГіlo с хитрыми случаями.

В конце концов мы распределяем в колонну "Статус" dataframe цепь назначенного по умолчанию "OK" во всех линиях, и despuГ©s цепь "Repeated" sГіlo в те, которые dataframe.repeated() обнаруживает segГєn колонну "Интерфейс IP", и despuГ©s цепь одинокий "Overlapped" в те, "Нетворк Адд" которых фигурировал в списке, что мы построили в шаге 4.

AsГ - которые мы увидим cГіmo, как каждый из этих шагов делает:

, Но прежде всего, исправлять данные о примере, который ты помещаешь, так как случай 20.85.51.0/23 не vГЎlido из-за того, что имеет бит host по отношению к 1. DeberГ, - когда его быть 20.85.50.0/23. И следующий 20.85.52.0/24, хотя он vГЎlido, не producirГ - в solapamiento с предыдущим. Для того, чтобы он это произвел, я это меняю на 20.85.51.0/24

Из шага, привожу в беспорядок линии для того, чтобы не остались вместе IPs, которые хитрые, и aГ±ado другой случай, в котором "Нетворк Адд" - тот же самый, но "Интерфейс Ip" отличается, для того, чтобы asГ - он был mГЎs difГ-cil.

Так что мой dataframe:

Site IP     Site Name   Instance    Interface Name  Network Add     Interface IP
20.X.X.4    ROUTER4     VPRN1       interface4      20.85.50.0/23   20.85.50.1
20.X.X.1    ROUTER1     VPRN1       interface1      20.49.128.0/17  20.49.208.129   
20.X.X.5    ROUTER5     VPRN1       interface5      20.85.51.0/24   20.85.51.1
20.X.X.2    ROUTER2     VPRN1       interface2      20.84.34.0/24   20.84.34.3
20.X.X.6    ROUTER3     VPRN1       interface3      20.84.34.0/24   20.84.34.5
20.X.X.3    ROUTER3     VPRN1       interface3      20.84.34.0/24   20.84.34.3

1. Извлекать колонну

Этот - просто:

networks = list(df["Network Add"])

2. Упорядочивать колонну

Это необходимо для того, чтобы IPs, которые равны, остались объединенными. И мы будем считать tambiГ©n "равные" (на данный момент) те, которые solapen.

мы Нуждаемся в том, чтобы написать одну funciГіn, что смог сравнивать двух IPs в формате CDIR и возвратил 0, если они равны (или solapan),-1, если первая предыдущая второй, или 1 в противоположном случае. SerГ - в asГ-:

from ipaddress import IPv4Network

def compare(add1, add2):
  add1 = IPv4Network(add1, strict=False)
  add2 = IPv4Network(add2, strict=False)
  if add1.overlaps(add2):
    return 0
  else:
    return add1.compare_networks(add2)

, Чтобы мочь использовать эту funciГіn как key, (так в sorted() как despuГ©s в groupby()) мы нуждаемся в том, чтобы преобразовать ее с помощью functools.cmp_to_key():

from functools import cmp_to_key
compare_key = cmp_to_key(compare)

, Хотя это в конце концов упорядочивает сети, - один instrucciГіn:

networks = sorted(networks, key=compare_key)

Результат однажды аккуратные мы видим, что он оставил вместе тех, которые idГ©nticas или solapan:

['20.49.128.0/17',
 '20.84.34.0/24',
 '20.84.34.0/24',
 '20.84.34.0/24',
 '20.85.50.0/23',
 '20.85.51.0/24']

3. Группировать

from itertools import groupby

grupos = groupby(networks, key=compare_key)

Это crearГЎ несколько разведеных групп. В каждой группе может быть:

  • Единственная IP
  • Ты Изменяешь IPs, которые idГ©nticas (segГєn колонна "Нетворк Адд"
  • Несколько IPs, который считалась равной, потому что solapaban

4. Систематизировать

Результат, который у нас есть в grupos, - iterable. В каждый iteraciГіn он возвращает нам tupla, первый элемент которого - ключ (он не интересует нас, мы можем игнорировать ее) и второй элемент - другой iterable, который мы можем превращать в список, чтобы получать члены этой группы.

мы Хотим остаться одинокими с теми случаями, которые соответствуют в solapamientos, и обнаруживаем этих, потому что, если мы обращаем в набор (set()) адреса каждой группы, те группы, которые соответствуют адресам idГ©nticas или индивиды tendrГЎn единственный элемент (так как тип set() удаляет дубликаты).

AsГ - так как мы используем эту идею, чтобы оставлять себе sГіlo случаи solapes:

repetidas = []

for _, g in grupos:
  grupo = list(g)
  if len(set(grupo))>1:
    solapadas.extend(grupo)

конечный Шаг: сохранять результат в dataframe

df["Status"] = "OK"
df.loc[df.duplicated("Interface IP", False), "Status"] = "Duplicated"
df.loc[df["Network Add"].isin(solapadas), "Status"] = "Overlapped"

мы Можем наблюдать, что результат правилен (он помнит, что habГ - в приведенный в беспорядок линии, чтобы видеть, aГєn asГ - функционировало ли оно правильно):

    Site IP Site Name Instance  ...     Network Add   Interface IP      Status
0  20.X.X.4   ROUTER4    VPRN1  ...   20.85.50.0/23     20.85.50.1  Overlapped
1  20.X.X.1   ROUTER1    VPRN1  ...  20.49.128.0/17  20.49.208.129          OK
2  20.X.X.5   ROUTER5    VPRN1  ...   20.85.51.0/24     20.85.51.1  Overlapped
3  20.X.X.2   ROUTER2    VPRN1  ...   20.84.34.0/24     20.84.34.3  Duplicated
4  20.X.X.6   ROUTER3    VPRN1  ...   20.84.34.0/24     20.84.34.5          OK
5  20.X.X.3   ROUTER3    VPRN1  ...   20.84.34.0/24     20.84.34.3  Duplicated
5
ответ дан 01.12.2019, 10:40
  • 1
    Abulafia, спасибо за твой respuesa, едва смог разыгрывать недостаток, который у меня есть, чтобы получать network address, я протестирую твой код и я комментирую тебе. – juanpb12 28.11.2019, 20:28
  • 2
    Деталь. Как está мой có я говорю, что он необходим, что direcció n CDIR, которым ты обеспечиваешь его, был правилен, а именно, у которого были совсем 0 в части host. Например, одна как эта не serí в vá lida: 192.23.34.254/24, и если появлялась así producirí в excepció n. У тебя есть возможность того, чтобы, вместо excepció n, допустите ее, но считая тогда, что часть клиент serí в совсем нули, а именно, что serí в эквивалент 192.23.34.0/24. Скажи мне, предстает ли этот случай перед тобой. – abulafia 28.11.2019, 20:32
  • 3
    Пока я пытаюсь с примером и он дает мне эту ошибку: line 25, in < module> networks = list (df [" Network Add"]) TypeError: ' list' object is not callable – juanpb12 28.11.2019, 20:44
  • 4
    У тебя есть в твоей программе какая-то так называемая переменная list. Назови ее. Это не хорошая идея использовать как имена переменных идентификаторов языка :-) Забота несмотря на то, что звонит в переменные list, dict, id, и т.д... Если тебе не приходит в голову лучшее имя для них, помести им guió n внизу в конце концов, ej: list_ – abulafia 28.11.2019, 20:53
  • 5
    Уважаемый, я это решил используя networks = df [" Network Add"] .tolist (), но проблема сейчас состоит в том, что не функционирует следующая линия: networks = sorted (networks, key=compare_key), бросая sigueinte ошибку: AddressValueError: Десятичный Only digits permitted in ' 20' in ' 20.49.128.0' – juanpb12 28.11.2019, 20:55