2009-05-27 5 views
1

Ich habe ein Skript, das eine Reihe von IP-Adressen durchläuft und überprüft die IP-Clients gegen sie.Überprüfen Besucher IP gegen eine Tabelle von IPs. Einige Wildcards

//filter IP address list 
$ip = array(); 
$ip[] = '10.10.5.*'; 
$ip[] = '234.119.260.65'; 
$ip[] = '234.119.254.2'; 

function testIP($ip){ 
//testing that correct IP address used 
for($i=0, $cnt=count($ip); $i<$cnt; $i++) { 
    $ipregex = preg_replace(”/\./”, “\.”, $ip[$i]); 
    $ipregex = preg_replace(”/\*/”, “.*”, $ipregex); 

    if(preg_match('/'.$ipregex.'/', $_SERVER[REMOTE_ADDR])){ 
    // apply filter 
    return true; 
    } 
    //do not apply filter 
    return false; 
} 

Die Sache ist, ich meine Liste von IP-Adressen in einer Tabelle sein will, und ich mag es so effizient wie möglich machen. Die einzige Möglichkeit, dies zu sehen, besteht darin, SELECT * zu wählen und jede Schleife nacheinander zu durchlaufen. Kann jemand einen effizienteren Weg sehen, dies zu tun? Vielleicht auf der MySQL-Seite der Dinge?

Antwort

4

Ändern der "*" auf "%" dann tun

SELECT 1 FROM filters WHERE '1.2.3.4' LIKE ip LIMIT 1 
+0

IMHO ist dies bei weitem die beste, einfachste Antwort - und es erfordert keine Schleife. +1 !! – Dutchie432

1

Sie cisco Stil verwenden können:

$ip[] = '10.10.5.0/24'; 

Match-Funktion unten

# Matches: 
# xxx.xxx.xxx.xxx  (exact) 
# xxx.xxx.xxx.[yyy-zzz] (range) 
# xxx.xxx.xxx.xxx/nn  (nn = # bits, cisco style -- i.e. /24 = class C) 
# 
# Does not match: 
# xxx.xxx.xxx.xx[yyy-zzz] (range, partial octets not supported) 
function matchIP($range, $ip) { 
    $result = true; 
    if (preg_match("`^(\d{1,3}) \. (\d{1,3}) \. (\d{1,3}) \. (\d{1,3})/(\d{1,2})$`x", $range, $regs)) { 
     # perform a mask match 
     $ipl = ip2long($ip); 
     $rangel = ip2long($regs[1] . "." . $regs[2] . "." . $regs[3] . "." . $regs[4]); 
     $maskl = 0; 
     for ($i = 0; $i< 31; $i++) { 
      if ($i < $regs[5]-1) { 
       $maskl = $maskl + pow(2,(30-$i)); 
      } 
     } 
     if (($maskl & $rangel) == ($maskl & $ipl)) $result = true; 
     else $result = false; 
    } else { 
     # range based 
     $maskocts = explode(".",$range); 
     $ipocts = explode(".",$ip); 
     # perform a range match 
     for ($i=0; $i<4; $i++) { 
      if (preg_match("`^\[(\d{1,3}) \- (\d{1,3})\]$`x", $maskocts[$i], $regs)) { 
       if (($ipocts[$i] > $regs[2]) || ($ipocts[$i] < $regs[1])) { 
        $result = false; 
       } 
      } else { 
       if ($maskocts[$i] != $ipocts[$i]) { 
        $result = false; 
       } 
      } 
     } 
    } 
    return $result; 
} 
+0

Das war wirklich nützlich, danke fürs Posten –

1

Wenn Sie Ihre Eingabe garantiert eine IP-Adresse zu sein (Sie ziehen es aus $_SERVER, so Gültigkeitsprüfung oder "Verständnis" der IP-Adresse ist ein No-Goa l hier):

//filter IP address list 
$ip = array(); 
$ip[] = '10.10.5.*'; 
$ip[] = '234.119.260.65'; 
$ip[] = '234.119.254.2'; 

function testIP($ip){ 
    //testing that correct IP address used 
    for($i=0, $cnt=count($ip); $i<$cnt; $i++) { 
    $ipregex = preg_replace("/\\./", "\\\\.", $ip[$i]); 
    $ipregex = preg_replace("/\\*/", "[.\\\\d]+", $ipregex); 

    if(preg_match("/^".$ipregex."$/", $_SERVER[REMOTE_ADDR])){ 
     // apply filter 
     return true; 
    } 
    } 
    //do not apply filter 
    return false; 
}