IP Adressen checken

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Antworten
Dvdscot
User
Beiträge: 10
Registriert: Donnerstag 27. April 2023, 11:46

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.
Sirius3
User
Beiträge: 18274
Registriert: Sonntag 21. Oktober 2012, 17:20

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.
Dvdscot
User
Beiträge: 10
Registriert: Donnerstag 27. April 2023, 11:46

Ohne das Modul zu benutzen.
Benutzeravatar
__blackjack__
User
Beiträge: 14056
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@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‽
“Vir, intelligence has nothing to do with politics!” — Londo Mollari
Benutzeravatar
__blackjack__
User
Beiträge: 14056
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

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()
“Vir, intelligence has nothing to do with politics!” — Londo Mollari
Benutzeravatar
DeaD_EyE
User
Beiträge: 1240
Registriert: Sonntag 19. September 2010, 13:45
Wohnort: Hagen
Kontaktdaten:

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.
sourceserver.info - sourceserver.info/wiki/ - ausgestorbener Support für HL2-Server
Benutzeravatar
__blackjack__
User
Beiträge: 14056
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

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
“Vir, intelligence has nothing to do with politics!” — Londo Mollari
Dvdscot
User
Beiträge: 10
Registriert: Donnerstag 27. April 2023, 11:46

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.
Antworten