我陷入困境,无法超越它:
我有一个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.3
和192.168.1.5
- 192.168.1.6
我正在考虑使用ip2long
函数将它们转换为整数并对其进行排序。但除此之外无法思考。
任何帮助将不胜感激。
提前谢谢:)
答案 0 :(得分:3)
您可以使用ip2long
http://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 group
$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 group是
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
答案 1 :(得分: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]);
}
}
完成上述所有操作后,请从Long转换回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;
}
注意:我使用了第三方函数(参考文献中列出)来获取2个字符串的公共部分。
答案 2 :(得分: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
)
演示