2009-02-27 3 views
48

주어진 IP4 점선 쿼드 IP를 CIDR 표기법 마스크와 비교하는 빠르고 간단한 방법을 찾고 있습니다.PHP 5에서 CIDR 마스크와 IP 대조?

IP의 범위가 일치하는지 확인해야하는 IP가 있습니다.

예 :

$ips = array('10.2.1.100', '10.2.1.101', '10.5.1.100', '1.2.3.4'); 

foreach ($ips as $IP) { 
    if (cidr_match($IP, '10.2.0.0/16') == true) { 
     print "you're in the 10.2 subnet\n"; 
    } 
} 

무엇 cidr_match()과 같을 것이다?

정말 간단 할 필요는 없지만 빠를 것이 좋습니다. 기본 제공/공통 기능 만 사용하는 것은 보너스입니다. (한 사람에게 내게 배를 보여주기는 하나, 배가 내 코드가 어디에 있는지 배 또는 그 패키지에 의존 할 수는 없습니다. 배포).

답변

64

경우에만 사용하는 IPv4의 : (비트 단위 '와'할 서브넷 마스크

  • 에/XX 변환 긴 정수
  • 로 된 IP와 서브넷 범위를 변환하는

    • 사용 ip2long() 즉, 결과 = 서브넷 '

    이 같은 일을해야 IP & 마스크)'그 것을 체크 '

    function cidr_match($ip, $range) 
    { 
        list ($subnet, $bits) = explode('/', $range); 
        $ip = ip2long($ip); 
        $subnet = ip2long($subnet); 
        $mask = -1 << (32 - $bits); 
        $subnet &= $mask; # nb: in case the supplied subnet wasn't correctly aligned 
        return ($ip & $mask) == $subnet; 
    } 
    
  • +0

    아마도 C# 버전을 게시 한 경우 이유를 파악할 수 있을까요? – Alnitak

    +0

    (위의 PHP 코드는 예를 들어 _does_에서 작동 함) – Alnitak

    +1

    마스크 계산은 64 비트 시스템에서 작동하지 않습니다. '$ mask = (-1 << (32 - $ bits)) & ip2long ('255.255.255.255');와 같은 것을 사용해야 할 것입니다. –

    1
    function cidr_match($ipStr, $cidrStr) { 
        $ip = ip2long($ipStr); 
        $cidrArr = split('/',$cidrStr); 
        $maskIP = ip2long($cidrArr[0]); 
        $maskBits = 32 - $cidrArr[1]; 
        return (($ip>>$maskBits) == ($maskIP>>$maskBits)); 
    } 
    
    +2

    이것은 32 비트 시스템에서는 작동하지 않습니다. match (1.2.3.4, 0.0.0.0/0)는 false를 반환하고 true를 반환합니다. –

    0

    나는 몇 줄을보고 싶습니다. 사람들이 저에게 제안한 예는 효과가없는 것 같습니다. 내가 이해하는 한 가지 이유는 CIDR 마스크 비트가 이진수이기 때문에 이진수에서 비트 시프트를 수행해야한다는 것입니다. 긴 IP를 바이너리로 변환하려고 시도했지만 최대 바이너리 숫자 제한이 발생했습니다. OK, 여기 몇 줄 ... 당신의 의견을 기다리고 있습니다.

    function cidr_match($ipStr, $cidrStr) { 
    
    $ipStr = explode('.', $ipStr); 
    foreach ($ipStr as $key => $val) { 
        $ipStr[$key] = str_pad(decbin($val), 8, '0', STR_PAD_LEFT); 
        } 
    $ip = ''; 
    foreach ($ipStr as $binval) { 
        $ip = $ip . $binval; 
        } 
    
    $cidrArr = explode('/',$cidrStr); 
    
    $maskIP = explode('.', $cidrArr[0]); 
    foreach ($maskIP as $key => $val) { 
        $maskIP[$key] = str_pad(decbin($val), 8, '0', STR_PAD_LEFT); 
        } 
    $maskIP = ''; 
    foreach ($ipStr as $binval) { 
        $maskIP = $maskIP . $binval; 
        } 
    $maskBits = 32 - $cidrArr[1]; 
    return (($ip>>$maskBits) == ($maskIP>>$maskBits)); 
    } 
    
    3

    일부 기능이 변경됨과

    • 분할

    function cidr_match($ip, $range) 
    { 
        list ($subnet, $bits) = explode('/', $range); 
        $ip = ip2long($ip); 
        $subnet = ip2long($subnet); 
        $mask = -1 << (32 - $bits); 
        $subnet &= $mask; 
        return ($ip & $mask) == $subnet; 
    } 
    
    +0

    다음은 CloudFlare의 IP를 확인하기위한 추가 구현입니다. [코드] $ ip \t \t = \t $ _SERVER [ "REMOTE_ADDR"]; $ c1 \t \t = \t cidr_match ($ ip, '204.93.240.0/24'); $ c2 \t \t = \t cidr_match ($ ip, '204.93.177.0/24'); $ c3 \t \t = \t 등. $ cTotal \t = \t round ($ c1 + $ c2 + $ c3 + ...); if ($ cTotal <1) die(); [/ code] –

    3

    내 기술 서브넷 마스크를 이용하여 비트 매칭 비트를 사용하여 폭발.

    function cidr_match($ip, $range){ 
        list ($subnet, $bits) = explode('/', $range); 
        $ip = substr(IP2bin($ip),0,$bits) ; 
        $subnet = substr(IP2Bin($subnet),0,$bits) ; 
        return ($ip == $subnet) ; 
    } 
    
    function IP2Bin($ip){ 
        $ipbin = ''; 
        $ips = explode(".",$ip) ; 
        foreach ($ips as $iptmp){ 
         $ipbin .= sprintf("%08b",$iptmp) ; 
        } 
        return $ipbin ; 
    } 
    
    37

    PHP 5.2 이후에 많은 방법이 깨졌습니다. 다음과 같은 솔루션 버전 5.2 이상에서 작동하지만 :

    function cidr_match($ip, $cidr) 
    { 
        list($subnet, $mask) = explode('/', $cidr); 
    
        if ((ip2long($ip) & ~((1 << (32 - $mask)) - 1)) == ip2long($subnet)) 
        { 
         return true; 
        } 
    
        return false; 
    } 
    

     
    cidr_match("1.2.3.4", "0.0.0.0/0"):   true 
    cidr_match("127.0.0.1", "127.0.0.1/32"): true 
    cidr_match("127.0.0.1", "127.0.0.2/32"): false 
    

    소스 http://www.php.net/manual/en/function.ip2long.php#82397 결과.

    +2

    PHP 5.6.5에서 작동하는지 확인했습니다. (Windows x86_64) – Adambean

    +0

    'cidr_match ("1.2.3.4", "0.0.0.0/0")'은 내 컴퓨터에서 false를 반환합니다 (PHP 5.5.13, Windows x64). –

    +1

    이것은 허용 된 대답이어야합니다. +1! – Sw0ut

    1

    Alnitak의 답변은 32/64 비트로 작동합니다.

    모든 국가에서 사용할 수있는 국가 별 IP 목록을 기반으로 한 신속한 스팸 차단을위한 쿠폰 버전입니다. 국가 IP 목록 또는 국가 IP 차단을위한 google (여기에 하나를 주어야 함, 해당 사이트 페이지 탐색에서 실제로 찾기 어려움)

    cidr ip 목록을 $ cidrs 문자열에 복사하여 붙여 넣으십시오. 그리고이 코드를 페이지 html 바로 전에 header.php 파일에 넣으십시오.

    국가 별 페이지 템플릿에서 애드 센스 사용을 필터링하는데도 사용할 수 있습니다.

    이것은 중급의 해결책으로 만 사용됩니다. 때로는 어제 빨리 클라이언트와 같은 것을 만들어야하기 때문에 여기 있습니다.

    //++++++++++++++++++++++ 
    //COUNTRY SPAM PROTECTOR 
    //speed: ~5ms @ 2000 cidrs 
    //comments start with # 
    //++++++++++++++++++++++ 
    $cidrs= 
    ' 
    #yourcountry 
    1.3.4.5/21 
    #mycountry 
    6.7.8.9/20 
    '; 
    //$cidrs.="\n".'123.12.12.12/32';//test, your ip 
    $cidrs_ar=preg_split('/\s+/',$cidrs,-1,PREG_SPLIT_NO_EMPTY); 
    [email protected]$_SERVER['REMOTE_ADDR']; 
    $iplong=ip2long($ip); 
    //var_export($cidrs_ar);var_export($ip);var_export($iplong); 
    if($iplong) 
        foreach($cidrs_ar as $cidr) 
        { 
        $ar=explode ('/', $cidr); 
        $netiplong=ip2long($ar[0]); 
        if($netiplong===false) continue; 
        $mask=intval(@$ar[1]); 
        if(!$mask) continue; 
        $bitmask=-1 <<(32-$mask); 
        if(($iplong & $bitmask) == ($netiplong & $bitmask)) 
         { 
         header('Location: http://www.someotherwebsite.com/',true,303); 
         exit; 
         } 
        } 
    
    1

    Net_IPv4 PEAR library도 사용할 수 있습니다.

    function cidr_match($ip, $net){ 
        include_once("Net/IPv4.php"); 
        $objIP = new Net_IPv4(); 
        return $objIP->ipInNetwork($ip, $net); 
    } 
    
    2

    IP의 CIDR 마스크를 테스트해야했습니다. 나는 완벽하게 잘 작동하는 훌륭한 설명과 소스 코드로 웹 사이트를 발견했다. 웹 사이트는 하루 중단이 존재 할 수 있기 때문에

    웹 사이트 http://pgregg.com/blog/2009/04/php-algorithms-determining-if-an-ip-is-within-a-specific-range/

    , 여기에 코드

    <?php 
    
    /* 
    * ip_in_range.php - Function to determine if an IP is located in a 
    *     specific range as specified via several alternative 
    *     formats. 
    * 
    * Network ranges can be specified as: 
    * 1. Wildcard format:  1.2.3.* 
    * 2. CIDR format:   1.2.3/24 OR 1.2.3.4/255.255.255.0 
    * 3. Start-End IP format: 1.2.3.0-1.2.3.255 
    * 
    * Return value BOOLEAN : ip_in_range($ip, $range); 
    * 
    * Copyright 2008: Paul Gregg <[email protected]> 
    * 10 January 2008 
    * Version: 1.2 
    * 
    * Source website: http://www.pgregg.com/projects/php/ip_in_range/ 
    * Version 1.2 
    * 
    * This software is Donationware - if you feel you have benefited from 
    * the use of this tool then please consider a donation. The value of 
    * which is entirely left up to your discretion. 
    * http://www.pgregg.com/donate/ 
    * 
    * Please do not remove this header, or source attibution from this file. 
    */ 
    
    
    // decbin32 
    // In order to simplify working with IP addresses (in binary) and their 
    // netmasks, it is easier to ensure that the binary strings are padded 
    // with zeros out to 32 characters - IP addresses are 32 bit numbers 
    Function decbin32 ($dec) { 
        return str_pad(decbin($dec), 32, '0', STR_PAD_LEFT); 
    } 
    
    // ip_in_range 
    // This function takes 2 arguments, an IP address and a "range" in several 
    // different formats. 
    // Network ranges can be specified as: 
    // 1. Wildcard format:  1.2.3.* 
    // 2. CIDR format:   1.2.3/24 OR 1.2.3.4/255.255.255.0 
    // 3. Start-End IP format: 1.2.3.0-1.2.3.255 
    // The function will return true if the supplied IP is within the range. 
    // Note little validation is done on the range inputs - it expects you to 
    // use one of the above 3 formats. 
    Function ip_in_range($ip, $range) { 
        if (strpos($range, '/') !== false) { 
        // $range is in IP/NETMASK format 
        list($range, $netmask) = explode('/', $range, 2); 
        if (strpos($netmask, '.') !== false) { 
         // $netmask is a 255.255.0.0 format 
         $netmask = str_replace('*', '0', $netmask); 
         $netmask_dec = ip2long($netmask); 
         return ((ip2long($ip) & $netmask_dec) == (ip2long($range) & $netmask_dec)); 
        } else { 
         // $netmask is a CIDR size block 
         // fix the range argument 
         $x = explode('.', $range); 
         while(count($x)<4) $x[] = '0'; 
         list($a,$b,$c,$d) = $x; 
         $range = sprintf("%u.%u.%u.%u", empty($a)?'0':$a, empty($b)?'0':$b,empty($c)?'0':$c,empty($d)?'0':$d); 
         $range_dec = ip2long($range); 
         $ip_dec = ip2long($ip); 
    
         # Strategy 1 - Create the netmask with 'netmask' 1s and then fill it to 32 with 0s 
         #$netmask_dec = bindec(str_pad('', $netmask, '1') . str_pad('', 32-$netmask, '0')); 
    
         # Strategy 2 - Use math to create it 
         $wildcard_dec = pow(2, (32-$netmask)) - 1; 
         $netmask_dec = ~ $wildcard_dec; 
    
         return (($ip_dec & $netmask_dec) == ($range_dec & $netmask_dec)); 
        } 
        } else { 
        // range might be 255.255.*.* or 1.2.3.0-1.2.3.255 
        if (strpos($range, '*') !==false) { // a.b.*.* format 
         // Just convert to A-B format by setting * to 0 for A and 255 for B 
         $lower = str_replace('*', '0', $range); 
         $upper = str_replace('*', '255', $range); 
         $range = "$lower-$upper"; 
        } 
    
        if (strpos($range, '-')!==false) { // A-B format 
         list($lower, $upper) = explode('-', $range, 2); 
         $lower_dec = (float)sprintf("%u",ip2long($lower)); 
         $upper_dec = (float)sprintf("%u",ip2long($upper)); 
         $ip_dec = (float)sprintf("%u",ip2long($ip)); 
         return (($ip_dec>=$lower_dec) && ($ip_dec<=$upper_dec)); 
        } 
    
        echo 'Range argument is not in 1.2.3.4/24 or 1.2.3.4/255.255.255.0 format'; 
        return false; 
        } 
    
    } 
    ?> 
    

    (I이 개발하지 않았다이며,이 (http://pgregg.com/)

    폴 그레그에 의해 개발되고있다
    37

    유사한 상황에서 symfony/http-foundation을 사용하여 끝났습니다.

    이 패키지를 사용하면 전자 모양은 다음과 같습니다.

    $ips = array('10.2.1.100', '10.2.1.101', '10.5.1.100', '1.2.3.4'); 
    
    foreach($ips as $IP) { 
        if (\Symfony\Component\HttpFoundation\IpUtils::checkIp($_SERVER['REMOTE_ADDR'], '10.2.0.0/16')) { 
         print "you're in the 10.2 subnet\n"; 
        } 
    } 
    

    또한 IPv6을 처리합니다.

    링크 : https://packagist.org/packages/symfony/http-foundation

    +0

    감사합니다.어떻게 든 Symfony 솔루션은 필자의 경우 올바르게 작동하지만 받아 들여지지는 않는다. – Xardas

    +0

    PHP, 작곡가 및 심포니가 매우 다른 이유 때문에 질문이 2009 년에 요청되었을 때 – Uberfuzzy

    +1

    이것은 가장 좋은 답변입니다. – Tek

    1

    아마이 사람에게 유용하다. 비트 마스크로

    // convert 12 => 255.240.0.0 
    // ip2long('255.255.255.255') == -1 
    $ip = long2ip((-1 << (32 - $bit)) & -1); 
    

    변환 IP 마스크 : IP 마스크로

    변환 비트 마스크

    // convert 255.240.0.0 => 12 
    
    // is valid IP 
    if (filter_var($ip, FILTER_VALIDATE_IP, FILTER_FLAG_IPV4) === false) { 
        throw new \InvalidArgumentException(sprintf('Invalid IP "%s".', $ip)); 
    } 
    
    // convert decimal to binary 
    $mask = ''; 
    foreach (explode('.', $ip) as $octet) { 
        $mask .= str_pad(decbin($octet), 8, '0', STR_PAD_LEFT); 
    } 
    
    // check mask 
    if (strpos('01', $mask) !== false) { 
        // valid 11111111111111111111111100000000 -> 255.255.255.0 
        // invalid 11111111111111111111111100000001 -> 255.255.255.1 
        throw new \InvalidArgumentException(sprintf('IP mask "%s" is not valid.', $ip)); 
    } 
    
    $bit = substr_count($mask, '1'); // bit mask 
    
    2

    여기에 그것을 할 수있는 한 빠른 64bit를 기능, 당신은 '돈 리턴 라인을 주석 처리하십시오 필요 없어. 예를 들어 유효한 CIDR 라우팅 접두어와 함께 또는없이 유효한 IPv4의 수락 주어진 IPv4를 주어진 CIDR 일치하는 경우 인라인 그것을 할 수 확인, 빨리 63.161.156.0/ 24 또는

    <?php 
    function cidr2range($ipv4){ 
    if ($ip=strpos($ipv4,'/')) 
    {$n_ip=(1<<(32-substr($ipv4,1+$ip)))-1; $ip_dec=ip2long(substr($ipv4,0,$ip)); } 
    else 
    {$n_ip=0;         $ip_dec=ip2long($ipv4);    } 
    $ip_min=$ip_dec&~$n_ip; 
    $ip_max=$ip_min+$n_ip; 
    #Array(2) of Decimal Values Range 
    return [$ip_min,$ip_max]; 
    #Array(2) of Ipv4 Human Readable Range 
    return [long2ip($ip_min),long2ip($ip_max)]; 
    #Array(2) of Ipv4 and Subnet Range 
    return [long2ip($ip_min),long2ip(~$n_ip)]; 
    #Array(2) of Ipv4 and Wildcard Bits 
    return [long2ip($ip_min),long2ip($n_ip)]; 
    #Integer Number of Ipv4 in Range 
    return ++$n_ip; 
    } 
    

    63.161.156.0 같은 예에서 으로

    <?php 
    $given_cidr='55.55.55.0/24'; 
    $given_ipv4='55.55.55.55'; 
    if(($range=cidr2range($given_cidr)) && 
    ($check=ip2long($given_ipv4))!==false && 
    $check>=$range[0] && $check<=$range[1]) 
    { 
    echo 'Yes, '.$given_ipv4.' is included in '.$given_cidr; 
    } 
    else 
    { 
    echo 'No, '.$given_ipv4.' is not included in '.$given_cidr; 
    } 
    

    는 다음과 같은 코드를 사용하지만 자르 할 수 있습니다 (CIDR 라우팅 접두사 또는없이) 해당 IP에 대한 배열로 전체 범위를 얻을 수 있기 때문에 예 25.25.25합니다.16분의 25 65536 개 요소 배열을 반환하고 당신은 쉽게 주어진 IPv4를 IP의 지정된 배열에 일치하는 경우 (또는 CIDR없이 확인을 빨리하기 위해 작은 라우팅 접두사

    <?php 
    $result=cidr2range($ipv4); 
    for($ip_dec=$result[0];$ip_dec<=$result[1];$ip_dec++) 
    $full_range[$ip_dec]=long2ip($ip_dec); 
    print_r($full_range); 
    

    를 사용하여 메모리가 부족할 수 있습니다 라우팅 접두사)

    <?php 
    #This code is checking if a given ip belongs to googlebot 
    $given_ipv4='74.125.61.208'; 
    $given_cidr_array=['108.59.93.43/32','108.59.93.40/31','108.59.93.44/30','108.59.93.32/29','108.59.93.48/28','108.59.93.0/27','108.59.93.64/26','108.59.93.192/26','108.59.92.192/27','108.59.92.128/26','108.59.92.96/27','108.59.92.0/27','108.59.94.208/29','108.59.94.192/28','108.59.94.240/28','108.59.94.128/26','108.59.94.16/29','108.59.94.0/28','108.59.94.32/27','108.59.94.64/26','108.59.95.0/24','108.59.88.0/22','108.59.81.0/27','108.59.80.0/24','108.59.82.0/23','108.59.84.0/22','108.170.217.128/28','108.170.217.160/27','108.170.217.192/26','108.170.217.0/25','108.170.216.0/24','108.170.218.0/23','108.170.220.0/22','108.170.208.0/21','108.170.192.0/20','108.170.224.0/19','108.177.0.0/17','104.132.0.0/14','104.154.0.0/15','104.196.0.0/14','107.167.160.0/19','107.178.192.0/18','125.17.82.112/30','125.16.7.72/30','74.125.0.0/16','72.14.192.0/18','77.109.131.208/28','77.67.50.32/27','66.102.0.0/20','66.227.77.144/29','66.249.64.0/19','67.148.177.136/29','64.124.98.104/29','64.71.148.240/29','64.68.64.64/26','64.68.80.0/20','64.41.221.192/28','64.41.146.208/28','64.9.224.0/19','64.233.160.0/19','65.171.1.144/28','65.170.13.0/28','65.167.144.64/28','65.220.13.0/24','65.216.183.0/24','70.32.132.0/23','70.32.128.0/22','70.32.136.0/21','70.32.144.0/20','85.182.250.128/26','85.182.250.0/25','80.239.168.192/26','80.149.20.0/25','61.246.224.136/30','61.246.190.124/30','63.237.119.112/29','63.226.245.56/29','63.158.137.224/29','63.166.17.128/25','63.161.156.0/24','63.88.22.0/23','41.206.188.128/26','12.234.149.240/29','12.216.80.0/24','8.34.217.24/29','8.34.217.0/28','8.34.217.32/27','8.34.217.64/26','8.34.217.128/25','8.34.216.0/24','8.34.218.0/23','8.34.220.0/22','8.34.208.128/29','8.34.208.144/28','8.34.208.160/27','8.34.208.192/26','8.34.208.0/25','8.34.209.0/24','8.34.210.0/23','8.34.212.0/22','8.35.195.128/28','8.35.195.160/27','8.35.195.192/26','8.35.195.0/25','8.35.194.0/24','8.35.192.0/23','8.35.196.0/22','8.35.200.0/21','8.8.8.0/24','8.8.4.0/24','8.6.48.0/21','4.3.2.0/24','23.236.48.0/20','23.251.128.0/19','216.239.32.0/19','216.252.220.0/22','216.136.145.128/27','216.33.229.160/29','216.33.229.144/29','216.34.7.176/28','216.58.192.0/19','216.109.75.80/28','216.74.130.48/28','216.74.153.0/27','217.118.234.96/28','208.46.199.160/29','208.44.48.240/29','208.21.209.0/28','208.184.125.240/28','209.185.108.128/25','209.85.128.0/17','213.200.103.128/26','213.200.99.192/26','213.155.151.128/26','199.192.112.224/29','199.192.112.192/27','199.192.112.128/26','199.192.112.0/25','199.192.113.176/28','199.192.113.128/27','199.192.113.192/26','199.192.113.0/25','199.192.115.80/28','199.192.115.96/27','199.192.115.0/28','199.192.115.128/25','199.192.114.192/26','199.192.114.0/25','199.223.232.0/21','198.108.100.192/28','195.16.45.144/29','192.104.160.0/23','192.158.28.0/22','192.178.0.0/15','206.160.135.240/28','207.223.160.0/20','203.222.167.144/28','173.255.125.72/29','173.255.125.80/28','173.255.125.96/27','173.255.125.0/27','173.255.125.128/25','173.255.124.240/29','173.255.124.232/29','173.255.124.192/27','173.255.124.128/29','173.255.124.144/28','173.255.124.160/27','173.255.124.48/29','173.255.124.32/28','173.255.124.0/27','173.255.124.64/26','173.255.126.0/23','173.255.122.128/26','173.255.122.64/26','173.255.123.0/24','173.255.121.128/26','173.255.121.0/25','173.255.120.0/24','173.255.117.32/27','173.255.117.64/26','173.255.117.128/25','173.255.116.192/27','173.255.116.128/26','173.255.116.0/25','173.255.118.0/23','173.255.112.0/22','173.194.0.0/16','172.102.8.0/21','172.253.0.0/16','172.217.0.0/16','162.216.148.0/22','162.222.176.0/21','180.87.33.64/26','128.177.109.0/26','128.177.119.128/25','128.177.163.0/25','130.211.0.0/16','142.250.0.0/15','146.148.0.0/17']; 
    echo '<pre>'; 
    $in_range=false; 
    if (($given_ipv4_dec=ip2long($given_ipv4))!==false) 
    { 
    foreach($given_cidr_array as $given_cidr){ 
    if(($range=cidr2range($given_cidr)) && 
    $given_ipv4_dec>=$range[0] && $given_ipv4_dec<=$range[1]) 
    { 
    $in_range=true; 
    echo $given_ipv4.' matched '.$given_cidr.' ('.join(array_map('long2ip',$range),' - ').")\n"; 
    } 
    } 
    } 
    echo $given_ipv4.' is probably'.($in_range?'':' not').' a Googlebot IP'; 
    

    빠른 입력을 확인하지 않는 기능을 실행하려면 있지만 공식적으로는 다음과 같은 정규식

    #^(?:((?:0)|(?:2(?:(?:[0-4][0-9])|(?:5[0-5])))|(?:1?[0-9]{1,2}))\.((?:0)|(?:2(?:(?:[0-4][0-9])|(?:5[0-5])))|(?:1?[0-9]{1,2}))\.((?:0)|(?:2(?:(?:[0-4][0-9])|(?:5[0-5])))|(?:1?[0-9]{1,2}))\.((?:0)|(?:2(?:(?:[0-4][0-9])|(?:5[0-5])))|(?:1?[0-9]{1,2}))(?:/((?:(?:0)|(?:3[0-2])|(?:[1-2]?[0-9]))))?)$# 
    
    일치하는 문자열이어야한다

    당신은

    <?php 
    #Requiring cidr2range shown above function 
    function cidr_match($mixed_ip,$mixed_cidr){ 
    if (!is_array($mixed_ip)){ 
    $string_mode=true; 
    $mixed_ip=[$mixed_ip=>0]; 
    } 
    else $mixed_ip=array_fill_keys($mixed_ip,0); 
    if (!is_array($mixed_cidr)) $mixed_cidr=[$mixed_cidr]; 
    foreach($mixed_ip as $ip => &$result) 
    foreach($mixed_cidr as $cidr) 
    { 
    if(($range=cidr2range($cidr)) && 
    ($check=ip2long($ip))!==false && 
    $check>=$range[0] && $check<=$range[1]){ 
    $result=$cidr; 
    break; 
    } 
    } 
    $mixed_ip=array_filter($mixed_ip); 
    return $string_mode?($mixed_ip?true:false):$mixed_ip; 
    } 
    
    print '<pre>'; 
    
    #Your example 
    $ips = array('10.2.1.100', '10.2.1.101', '10.5.1.100', '1.2.3.4'); 
    
    foreach ($ips as $IP) { 
        if (cidr_match($IP, '10.2.0.0/16') == true) { 
         print "you're in the 10.2 subnet\n"; 
        } 
    } 
    
    
    #Also working with IP array and/or CIDR array 
    #If IP array is given then return an array containing IP (keys) matching CIDR (values) 
    $result=cidr_match($ips,['20.2.0.0/16','10.2.0.0/15']); 
    foreach($result as $ip => $cidr){ 
    print "$ip is in the $cidr subnet\n"; 
    } 
    

    당신은 다음을 사용하여 자신의 기능을 컴파일 할 수 따르고 질문에 그런 공식 대답을하는 기능

    <?php 
    if (is_string($ipv4) && preg_match('#^(?:((?:0)|(?:2(?:(?:[0-4][0-9])|(?:5[0-5])))|(?:1?[0-9]{1,2}))\.((?:0)|(?:2(?:(?:[0-4][0-9])|(?:5[0-5])))|(?:1?[0-9]{1,2}))\.((?:0)|(?:2(?:(?:[0-4][0-9])|(?:5[0-5])))|(?:1?[0-9]{1,2}))\.((?:0)|(?:2(?:(?:[0-4][0-9])|(?:5[0-5])))|(?:1?[0-9]{1,2}))(?:/((?:(?:0)|(?:3[0-2])|(?:[1-2]?[0-9]))))?)$#',$ipv4)) 
    { 
    #This is a valid ipv4 with or without CIDR Routing Prefix 
    $result=cidr2range($ipv4); 
    print_r($result); 
    } 
    

    를 사용하기 전에 입력을 확인 하려면 예를 들어,이 몇 라인이 당신을 도왔을 희망 ...

    관련 문제