1

IPの配列をループし、クライアントのIPをそれらに対してチェックするスクリプトがあります。

//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;
}

重要なのは、IPアドレスのリストをテーブルに入れて、できるだけ効率的にしたいということです。これを行うために私が見ることができる唯一の方法は、SELECT *を実行し、それぞれを順番にループすることです。誰かがこれを行うためのより効率的な方法を見ることができますか?おそらくMySQL側のことですか?

4

3 に答える 3

4

「*」を「%」に変更してから実行します

SELECT 1 FROM filters WHERE '1.2.3.4' LIKE ip LIMIT 1
于 2009-05-27T09:19:50.470 に答える
1

シスコスタイルを使用できます。

$ip[] = '10.10.5.0/24';

以下の一致機能

# 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;
}
于 2009-05-27T09:29:15.410 に答える
1

入力がIPアドレスであることが保証されている場合(入力を引き出すため、IPアドレスの$_SERVER有効性チェックまたは「理解」はここでは目標ではありません):

//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;
}
于 2009-05-27T10:10:32.597 に答える