Sascha: Sucharithmetik IP-Adresse / Wildcard

Hallo Forum!

Bei mir hat sich folgendes Problem eingeschlichen. Ich habe eine Suchmaske gestaltet die unter anderem nach einer IP-adresse sucht, wenn diese in der Datenbank vorhanden ist kommt dann die entsprechende Weiterführung. Ich möchte nun, dass der user nach IP-Bereichen suchen kann. Also der User gibt z.B. ein 139.13.25.* dann sollen alle Datensätze die eine IP-adresse im Bereich 139.13.25.1 bis 139.13.25.255 angezeigt werden. Aber auch die Eingabe 139.13.*.25
sollte möglich sein, angezeigt sollte hier dann sämtliche Einträge mit IP 139.13.1.25 ... 139.13.255.25.

Für mich kommt noch Problemmatisch hinzu, dass die IP Adressen in der DB als long abgelegt wurden.

Kann mir jemand weiterhelfen? Ich habe schon unter einigen den PHP-Seiten rumgeschaut aber nichts wirklich, für mich, nützliches gefunden.

Für Eure hilfe bin ich wirklich dankbar

viele Grüße

Sascha

  1. Hallo,
    da ich gerade im Büro sitze hier ne kurze Erklärung...

    Speicher die IPs als "varache" in der DB.

    Dann fragst du sie ab

    .... WHERE ip is LIKE '$ip';

    das gibt du dann wieder aus.

    Wenn ich zuhause bin, kann ich mehr schreiben

    MFG
    Andavos

    1. Hallo Andavos,

      wenn ich Dich richtig verstanden habe soll ich die IP als kompletten String in DB ablegen?!

      Das wäre schön wenn ich es machen könnte, nur das Problem ist dieses.. die DB besteht bereits mit gut und gerne über 2500 IP-Adressen. Die DB benötigt leider die IP im format Long..naja die IP wird von anderer Stelle auch noch weiter verarbeitet...

      Also bleibt mir nichts anderes übrig als mit "magie" sprich PHP so geschickt zu lösen dass ich die DB via Long abfrage. Naja Between das ist ja auch noch alles möglich. Ich selber versuch es mit Bitweises verunden.. aber klappte halt noch nicht.

      Deshalb brauche ich hilfe ;-)

      viele grüße

      Sascha

      1. Halihallo Sascha

        Das wäre schön wenn ich es machen könnte, nur das Problem ist dieses.. die DB besteht bereits mit gut und gerne über 2500 IP-Adressen. Die DB benötigt leider die IP im format Long..naja die IP wird von anderer Stelle auch noch weiter verarbeitet...

        Ist wesentlich klüger, denn die Verarbeitung von Strings ist generell langsam. Besonders
        bei VARCHAR's. Ein CHAR(15) wäre schon etwas klüger, UNSIGNED SMALLINT(5) ist das Beste.

        Also bleibt mir nichts anderes übrig als mit "magie" sprich PHP so geschickt zu lösen dass ich die DB via Long abfrage. Naja Between das ist ja auch noch alles möglich. Ich selber versuch es mit Bitweises verunden.. aber klappte halt noch nicht.

        Gibt es nur ein '*' in einer Abfrage? - Berechne die "kleinste IP" und die "grösste IP"
        für die Abfrage und erstelle einen SELECT, der die IP auf diesen Bereich prüft (BETWEEN
        ist dafür möglich). Den unsigned long kannst du ja ziemlich einfach Berechnen (Addition
        von Potenzen). Wo genau ist das Problem?

        Viele Grüsse

        Philipp

        --
        RTFM! - Foren steigern das Aufkommen von Redundanz im Internet, danke für das lesen der Manuals.
        Selbstbedienung! - Das SelfForum ist ein Gratis-Restaurant mit Selbstbedienung, Menüangebot steht in den </faq/> und dem </archiv/>.
        1. Halihallo zurück :-)

          Gibt es nur ein '*' in einer Abfrage? - Berechne die "kleinste IP" und die "grösste IP"

          Na es gibt nur ein '*' aber auch wenn zb. 139.13 eingeben wird soll natürlich der rest eingeben werden...

          für die Abfrage und erstelle einen SELECT, der die IP auf diesen Bereich prüft (BETWEEN
          ist dafür möglich). Den unsigned long kannst du ja ziemlich einfach Berechnen (Addition
          von Potenzen). Wo genau ist das Problem?

          habe zwar nicht den druchblick was Du jetzt meinst mit addition.. aber so langsam schimmerts bei mir...

          werde mich mal jetzt an meiner funktion versuchen...mal sehen was daraus wird :-)

          danke für den denkanstoss

          1. Halihallo Sascha

            für die Abfrage und erstelle einen SELECT, der die IP auf diesen Bereich prüft (BETWEEN
            ist dafür möglich). Den unsigned long kannst du ja ziemlich einfach Berechnen (Addition
            von Potenzen). Wo genau ist das Problem?
            habe zwar nicht den druchblick was Du jetzt meinst mit addition..

            War ein IMHO ein schlechter Vorschlag von mir. Zu einer Sucheingabe berechnet man die
            "grössste und kleinste IP" (die Addition von Potenzen: 255.255 => 255 + 255*2^8, ...)
            und selektiert danach.
            Den Vorschlag von Sven mit Maske finde ich jedoch besser, kam mir nicht in den Sinn.
            Nun gut, ggf. wäre mein Vorschlag zwar nicht so schön und sicher nicht so flexibel, aber
            bei grossen Datenmengen performanter (ein Index über die IP's kann verwendet werden).
            Aber Schönheit vor Performance :-)

            Vielleicht noch um zu verdeutlichen:

            255.127.*.15

            Der Intervall:
              255.127.0.15 - 255.127.255.15

            255.127.0.15 = 15 + 0*2^8 + 127*2^16 + 255*2^24 = ip_low
            255.127.255.15 = 15 + 255*2^8 + 127*2^16 + 255*2^24 = ip_high

            =>

            ... IP BETWEEN ip_low AND ip_high

            Viele Grüsse

            Philipp

            --
            RTFM! - Foren steigern das Aufkommen von Redundanz im Internet, danke für das lesen der Manuals.
            Selbstbedienung! - Das SelfForum ist ein Gratis-Restaurant mit Selbstbedienung, Menüangebot steht in den </faq/> und dem </archiv/>.
            1. Hallo Phillip!

              jetzt ist mir einiges klar geworden :-) ich lag wohl zu lange unter Sonne...

              vielen Dank für Deine geduldige hilfe

              Gruß

              Sascha

      2. Moin!

        Ich selber versuch es mit Bitweises verunden.. aber klappte halt noch nicht.

        Das ist aber der beste Ansatz dafür.

        Das Problem dürfte sein, die Benutzereingabe in eine vernünftige Maske zu verwandeln. Resultat sollte ein der Netzmaske ähnlicher Wert sein, wobei es, genau wie bei der Netzmaske, nicht zwingend erforderlich ist, dass links nur 1 und rechts nur 0 stehen - auch Mischungen sind möglich.

        Also: Du hast aufgrund irgendwelcher Feststellungen (ich nehme mal dein Beispiel mit * als dritten Part) die IP 192.168.*.23 gesucht - das ergibt als Maske 255.255.0.255 - bzw. deren Binärdarstellung.

        Wenn du jetzt prüfen willst, ob eine IP-Adresse in der DB in den gesuchten IP-Bereich kommt, prüfst du, ob DB-IP & Maske = gesuchte IP & Maske.

        Wenn du gut bist, erlaubst du als Sucheingabe dann nicht nur ein Sternchen für ein einzelnes IP-Element, sondern auch Maskenschreibweise (192.168.0.1/255.255.255.0) und CIDR-Notation (192.168.0.1/24). Wenn der Suchende dir die Maske gleich mitliefert (wobei hier wieder die Anmerkung gilt, dass die nicht zwingend links nur 1 und rechts nur 0 in binärer Darstellung haben muß - im Prinzip ist alles erlaubt), dürfte die Aufgabe am leichtesten sein, und die CIDR-Darstellung (da ist die Maske dann entsprechend zu bilden) sollte auch keine große Schwierigkeit darstellen.

        - Sven Rautenberg

        --
        ss:) zu:) ls:[ fo:} de:] va:) ch:] sh:) n4:# rl:| br:< js:| ie:( fl:( mo:|