2013-04-29 148 views
2

我被困在一個點,不能想到超越它:合併IP範圍與PHP

我有一個Ip範圍的列表,我需要合併它們,使他們作爲一個範圍。例如

192.168.1.1

192.168.1.2

192.168.1.3

192.168.1.5

192.168.1.6

我需要他們的俱樂部進入IP範圍。對於這種情況,這將是192.168.1.1 - 192.168.1.3192.168.1.5 - 192.168.1.6

我想用ip2long功能和分類將其轉換到這些整數。但除此之外無法思考。

任何幫助,將不勝感激。

感謝提前:)

+0

'ip2long'功能夠好,不是嗎? – Raptor 2013-04-29 06:04:41

+0

我正在考慮使用相同的。但不知道在php – Aditi 2013-04-29 06:08:08

+0

中使用natsort @Aditi什麼是你的ip列表?陣列? – 2013-04-29 06:17:45

回答

3

您可以使用ip2longhttp://php.net/manual/en/function.ip2long.php含有的(IPv4)的互聯網協議地址點綴與此正確的地址的字符串,你可以有一個範圍像

echo ip2long('192.168.1.1');//-1062731519 

echo ip2long('192.168.1.6');//-1062731514 

轉換與此你可以檢查用戶的IP範圍,...有效或...

例如,如果用戶IP在192.168.1.1-192.168.1.6範圍內echo 'hello';

//http://www.php.net/manual/en/function.ip2long.php#81030 
function in_ip_range($ip_one, $ip_two=false){ 
    if($ip_two===false){ 
    if($ip_one==$_SERVER['REMOTE_ADDR']){ 
     $ip=true; 
    }else{ 
     $ip=false; 
    } 
    }else{ 
    if(ip2long($ip_one)<=ip2long($_SERVER['REMOTE_ADDR']) && ip2long($ip_two)>=ip2long($_SERVER['REMOTE_ADDR'])){ 
     $ip=true; 
    }else{ 
     $ip=false; 
    } 
    } 
    return $ip; 
} 
//usage 
if(in_ip_range('192.168.1.1','192.168.1.6')){ 
    echo 'hello'; 
} 

IP組

$list=array(
    '192.168.1.1', 
    '192.168.1.2', 

    '192.168.1.3', 

    '192.168.1.5', 

    '192.168.1.6', 
    '192.168.1.6', 
    '192.168.1.9' 
); 
$Grouplist=''; 
foreach($list as $ip){ 
     $ip2long=ip2long($ip); 
     if(is_array($Grouplist)){ 
      $is_group=false; 
      foreach($Grouplist as $Key=>$Range){ 
       $Range=explode("/",$Range); 
       if(($Range[0]-1)<$ip2long and $ip2long<($Range[1]+1)){ 
         $is_group=true; 
         continue; 
       }elseif(($Range[0]-1)==$ip2long){ 
         $Grouplist[$Key]=$ip2long.'/'.$Range[1]; 
         $is_group=true; 
       }elseif(($Range[1]+1)==$ip2long){ 
         $Grouplist[$Key]=$Range[0].'/'.$ip2long; 
         $is_group=true; 
       } 
      } 
      if(!$is_group) 
      { 
        $Grouplist[]=($ip2long).'/'.($ip2long); 
      } 
     }else{ 
      $Grouplist[]=($ip2long).'/'.($ip2long); 
     } 
} 
    print_r($Grouplist); 

輸出:

Array 
(
    [0] => -1062731519/-1062731517 
    [1] => -1062731515/-1062731514 
    [2] => -1062731511/-1062731511 
) 

,如果轉換到IP組是

foreach($Grouplist as $Val){ 
    $Range=explode("/",$Val); 
    echo long2ip($Range[0])."/".long2ip($Range[1])."\n"; 
} 

輸出

192.168.1.1/192.168.1.3 
192.168.1.5/192.168.1.6 
192.168.1.9/192.168.1.9 
+0

但這不回答OP的問題。 OP想分組的IP – Raptor 2013-04-29 06:22:58

+0

我等待@Aditi回答什麼是IP列表?陣列? – 2013-04-29 06:25:43

+0

@mohammadmohsenipur這是一個數組.. – Aditi 2013-04-29 06:31:46

2

這裏是我的回答:

$ip_list = array('192.168.1.1', '192.168.1.2', '192.168.1.3', '192.168.1.5', '192.168.1.6'); 
$ip_long_list = array(); 
foreach($ip_list as $ip) { 
    $ip_long_list[] = ip2long($ip); 
} 
unset($ip_list); // no longer in use 
sort($ip_long_list); // sort it 

$result = array(); 
$cnt_group = 0; 
for($i = 0; $i < count($ip_long_list)-1; $i++) { 
    if($i == 0) { 
    $result[$cnt_group] = array($ip_long_list[0]); // initialize 1st group 
    continue; 
    } 
    if(abs($ip_long_list[$i] - $ip_long_list[$i+1]) == 1) { 
    // they are in series, group it. 
    $tmp_array = $result[$cnt_group]; // get back the array 
    $tmp_array[] = $ip_long_list[$i]; // push item into array 
    $result[$cnt_group] = $tmp_array; 
    unset($tmp_array); // remove to save memory 
    } else { 
    // they are separate. next group. 
    $cnt_group++; 
    $result[$cnt_group] = array($ip_long_list[1]); 
    } 
} 

畢竟以上,從長轉換回IP。

foreach($result as $ip_long_group) { 
    $first_ip = long2ip($ip_long_group[0]); 
    $last_ip = long2ip($ip_long_group[count($ip_long_group)-1]; 

    $common_parts = longest_common_substring(array($first_ip, $last_ip)); 

    echo $common_parts . str_replace($common_parts, '', $first_ip) . '-' . str_replace($common_parts, '', $last_ip) . PHP_EOL; 
} 

注:我使用的第三方功能(在參考中列出),以獲得兩個字符串的公共部分。

參考:longest_common_substring()

+0

檢查手動方法是否工作(請參閱我的答案)。我沒有使用ip2long。 – 2013-04-29 12:09:55

1

手動方法來獲取範圍(不使用ip2long):

<?php 
$ip_addressess=array(
    '192.168.1.1', '192.168.1.2', '192.168.1.3', '192.168.1.5', '192.168.1.6', '192.168.1.7', '192.168.1.9', '192.168.1.10', '192.168.1.11', '192.168.1.15', '192.168.1.16', '192.168.1.17'); 

foreach($ip_addressess as $ip_address){ 
    $break_ip[] = explode('.', $ip_address); //break ip address 
} 
foreach($break_ip as $break){ 
    $numbers[] = $break[3]; //get last number of ip address 
} 
$commaList_ipaddress = implode(',', $numbers); //generate comma separated list of last digits of ip address 
$missing = array(); 
$a =0 ; 
for ($i = 1; $i <= max($numbers); $i++) { 
    if (!in_array($i, $numbers)) 
    {  
     $missing[] = $i; 
    $a++; 

    } else{ 
    $new_ip_ranges[$a][] = $i;  
    } 

} 
$new_ip_ranges = array_values($new_ip_ranges); //rearrange the array 
foreach($new_ip_ranges as $new_range){ 
    $min = min($new_range); 
    $max = max($new_range);  
    $min_range = $break_ip[0][0].'.'.$break_ip[0][1].'.'.$break_ip[0][2].'.'.$min; 
    $max_range = $break_ip[0][0].'.'.$break_ip[0][1].'.'.$break_ip[0][2].'.'.$max;  
    $range[] = $min_range .'-'.$max_range; 

} 
echo '<pre>'; 
print_r($range); 


?> 

輸出:

Array 
(
    [0] => 192.168.2.1-192.168.2.3 
    [1] => 192.168.2.5-192.168.2.7 
    [2] => 192.168.2.9-192.168.2.11 
    [3] => 192.168.2.15-192.168.2.17 
) 

演示在CodeFiddle>>

+0

是的,這也是可能的,但是如果IP範圍類似於:'192.168.1.1'到'192.168.2.1',它將不起作用。 – Raptor 2013-04-30 02:26:53

+0

是的。我只是爲了更好的數組知識而手動完成的。感謝您的評論.. :) – 2013-04-30 03:15:39