Seite 1 von 1

IP Adressen checken

Verfasst: Donnerstag 29. Juni 2023, 12:16
von Dvdscot
Hallo,

ich habe folgende Datei

ip
0 111.184.80.32
1 28.6.84.150
2 200.116.131.199
3 93.244.54.112
4 30.254.146.232

1000 Einträge

Möchte checken ob die IP Adressen gültig sind, einmal ob es mehr als 4 Elemente pro Zeile gibt und ob jedes einzelne Element zwischen 0 und 255 liegt.

Code: Alles auswählen

import numpy as np
for i in range(df.shape[0]):
    ip_blocks = df.iloc[i, 0].split('.')
    if len(ip_blocks) > 4:
        ip = np.nan
    if ip_blocks < 0 or ip_blocks > 255:
        ip = np.nan

df
Am Ende will ich sehen wieviele falsche Einträge mit nan ersetzt wurden. Der Code klappt so nicht ganz, danke.

Re: IP Adressen checken

Verfasst: Donnerstag 29. Juni 2023, 13:15
von Sirius3
Dafür gibt es das ipaddress-Modul.

Wenn man über einen Index iteriert, macht man etwas falsch, wenn man mit Pandas Schleifen benutzt, auch meist.
`ip` wird nirgends benutzt. `ip_blocks` ist eine Liste mit Strings, die kann niemals größer oder kleiner einer Zahl sein.

Übrigens, für ip-Adressen gibt es das Modul ipaddress.

Re: IP Adressen checken

Verfasst: Donnerstag 29. Juni 2023, 13:21
von Dvdscot
Ohne das Modul zu benutzen.

Re: IP Adressen checken

Verfasst: Donnerstag 29. Juni 2023, 13:54
von __blackjack__
@Dvdscot: Die ``for``-Schleife ist schon falsch wenn das mit Pandas gelöst werden soll. Da würde man das `Series.str`-Attribut mit den Zeichenkettenfunktionen verwenden um die Spalte an dem "." in mehrere Spalten aufzuteilen, die in Zahlen wandeln, und die Tests dann mit Operationen auf dem DataFrame machen. Warum das ersetzen mit NaN und nicht einfach nur die gültigen Filtern?

Code: Alles auswählen

    potential_ip_data = ...

    data_as_colums = potential_ip_data[
        potential_ip_data["ip"].str.count(r"\.") == 3
    ]["ip"].str.split(".", expand=True)

    result = data_as_colums[
        data_as_colums.apply(
            lambda row: pd.to_numeric(row, "coerce").between(0, 255).all(),
            axis=1,
        )
    ]
Grundsätzlich ist Pandas dafür aber mal wieder das falsche Werkzeug. Eine Liste und das `ipaddress`-Modul würde zu deutlich verständlicherem Code führen. Warum soll das nicht verwendet werden‽

Re: IP Adressen checken

Verfasst: Donnerstag 29. Juni 2023, 14:06
von __blackjack__
Um den letzten Punkt mal zu demonstrieren:

Code: Alles auswählen

#!/usr/bin/env python3
from ipaddress import ip_address

from more_itertools import ilen, map_except


def main():
    ips = [
        "111.184.80.32",
        "28.6.84.256",
        "200.116.131.23",
        "93.244.x.112",
        "30.254.146.232.41",
        "30.254.146.232",
    ]
    print(ilen(map_except(ip_address, ips, ValueError)), "gültige IPs")


if __name__ == "__main__":
    main()

Re: IP Adressen checken

Verfasst: Donnerstag 29. Juni 2023, 16:17
von DeaD_EyE
Dvdscot hat geschrieben: Donnerstag 29. Juni 2023, 13:21 Ohne das Modul zu benutzen.
In deinem Beispiel nutzt du numpy und pandas.
Lern du erst mal vernünftig Python und bis dahin gibt es numpy/pandas-Verbot.


Ihr könnt euch gar nicht vorstellen, wie sehr mir das auf die Nerven geht.

Ohne `ipaddress` und ohne weitere Checks.

Code: Alles auswählen

def check_ip(ip: str) -> bool:
    try:
        for block in map(int, ip.split(".")):
            if not 0 <= block <= 255:
                return False
        return True
    except ValueError:
        return False
Leere Strings müssten auch ein True zurückliefern.
Ich habe aber auch keine Lust ip_address nachzuprogrammieren.

Re: IP Adressen checken

Verfasst: Donnerstag 29. Juni 2023, 16:48
von __blackjack__
Ob es vier Blöcke oder drei Trenner sind, sollte man IMHO schon noch prüfen:

Code: Alles auswählen

def check_ip(ip):
    try:
        return ip.count(".") == 3 and all(
            0 <= int(block) <= 255 for block in ip.split(".")
        )
    except ValueError:
        return False

Re: IP Adressen checken

Verfasst: Donnerstag 13. Juli 2023, 13:04
von Dvdscot
Vielen Dank für eure Hilfe, es war Teil einer Übungsaufgabe die recht simpel zu lösen war.

Nun kommt ein etwas größeres Projekt.