$badIp = "127.0.0.1|202.102.*.*|129.125.24.*"
function noAllowIps($ips)
{
$currentIp = GetIp(); //GetIp()函数返回的是获取当前访问者的ip
$ips = explode("|",$ips);
/*
我想在这里实现,把得到的访问者的ip和系统设计的禁用的ip($badIp)进行比较,
如果当前ip在系统禁用的ip之内则返回false,如果没有*号能配符我倒可以写,加了通配符我就不会写了。
127.0.0.1//则禁用127.0.0.1的ip地址
202.102.*.* //则禁用所有202.102开头的ip地址
29.125.24.*" //则禁用所有29.125.24开头的ip地址
*/}
{
$_bIp = explode(".", $bIp);
$_ip = explode(".", $ip);for ($i=0;$i<4;$i++)
{
if ($_bIp[$i] != $_ip[$i] || $_bIp[$i] != "*") return false;
}
return true;
}
function checkIP($ip, $bIp)
{
$_bIp = explode(".", $bIp);
$_ip = explode(".", $ip);for ($i=0;$i<4;$i++)
{
if ($_bIp[$i] != $_ip[$i] || $_bIp[$i] != "*") return false;
}
return true;
}
echo checkIP("127.0.0.1","127.0.0.1");//输出空
echo checkIP("127.0.0.1","127.0.0.8");//输出空
/*
楼上的朋友不好意思,只能证明你的思路是错的啊。
*/
function noAllowIps( $ips )
{
//$currentIp = GetIp(); //GetIp()函数返回的是获取当前访问者的ip
//$currentIp = "127.0.0.1";
// $currentIp = "202.102.0.2";
// $currentIp = "202.103.0.2";
//$currentIp = "129.125.23.2";
$currentIp = "129.125.24.2";
$ips = explode( "|", $ips );
$ip = explode( ".", $currentIp );
if( in_array( $currentIp, $ips ) )
{
exit( "out : ".$ip[0].".".$ip[1].".".$ip[2] );
}
elseif( in_array( $ip[0].".".$ip[1].".".$ip[2].".*", $ips ) )
{
exit( "out : ".$ip[0].".".$ip[1].".".$ip[2] );
}
elseif( in_array( "{$ip[0]}.{$ip[1]}.*.*", $ips ) )
{
exit( "out : ".$ip[0].".".$ip[1] );
}
exit( "out : ".$currentIp );
} noAllowIps( $badIp );?>
但一时也想不出来,谢谢楼上的phpboy了一会我测试一下你的。
当然这也是我个人的想法,希望大家指出错误。
function checkIP($ip, $bIp)
{
$_bIp = explode(".", $bIp);
$_ip = explode(".", $ip);
for ($i = 0; $i < 4; $i++)
{
if ($_bIp[$i] != $_ip[$i] and $_bIp[$i] != "*") return 1;
}
return 0;
}
返回1时候,ip不能匹配。返回0时候,ip匹配适合ip四段中,任意段使用通用匹配符
=========================
$badIp = "127.0.0.1|202.102.*.*|129.125.24.*|202.*.122.233|202.111.*.201|192.*.233.*|*.168.234.133";
function noAllowIps($currentIp)
{
global $badIp;
$ips = explode("|",$badIp);
/*
我想在这里实现,把得到的访问者的ip和系统设计的禁用的ip($badIp)进行比较,
如果当前ip在系统禁用的ip之内则返回false,如果没有*号能配符我倒可以写,加了通配符我就不会写了。
127.0.0.1//则禁用127.0.0.1的ip地址
202.102.*.* //则禁用所有202.102开头的ip地址
29.125.24.*" //则禁用所有29.125.24开头的ip地址
*/
$mc = array("."=>"\.","*"=>"(.[^\.]*?)");
$s = strtr($badIp,$mc);
return preg_match("/{$s}/",$currentIp) ? 'allow' : 'not allow';}
$badIp = "127.0.0.1|202.102.*.*|129.125.24.*";
$currentIp = GetIP(); //GetIp()函数返回的是获取当前访问者的ip
$ips = explode("|",$ips);
$a=explode("|",$badIp); //得到坏ip;数组
// print_r($a)."<br>";
$b=explode(".",$currentIp); //当前用户的ip;
// print_r($b);
for($i=0;$i<count($a);$i++)
{ $c=explode(".",$a[$i]); //分解出坏ip。。
// print_r($c);
for($j=0;$j<count($c[$i]);$j++) //用.分割出的坏ip循环
{
// echo "<br>".$c[2]."and".$c[3]."<br>";
if($c[2]=="*" and $c[3]=="*") // 202.102.*.* //则禁用所有202.102开头的ip地址
{
if($b[0]==$c[0] and $b[1]==$c[1])
{
echo $currentIp."坏ip"."<br>";
exit;
}
}
else if($b[0]==$c[0] and $b[1]==$c[1] and $b[2]==$c[2] and $b[3]==$c[3]) //127.0.0.1//则禁用127.0.0.1的ip地址
{
echo $currentIp."坏ip"."<br>";
exit;
}
else if($c[3]=="*") // 29.125.24.*" //则禁用所有29.125.24开头的ip地址
{
if($b[0]==$c[0] and $b[1]==$c[1] and $b[2]==$c[2])
{
echo $currentIp."坏ip"."<br>";
exit;
}
} }
}function GetIP() { //获取IP
if ($_SERVER["HTTP_X_FORWARDED_FOR"])
$ip = $_SERVER["HTTP_X_FORWARDED_FOR"];
else if ($_SERVER["HTTP_CLIENT_IP"])
//OsPHP.COM.CN
$ip = $_SERVER["HTTP_CLIENT_IP"];
else if ($_SERVER["REMOTE_ADDR"])
$ip = $_SERVER["REMOTE_ADDR"];
else if (getenv("HTTP_X_FORWARDED_FOR"))
//oSPHP.COM.CN
$ip = getenv("HTTP_X_FORWARDED_FOR");
else if (getenv("HTTP_CLIENT_IP"))
$ip = getenv("HTTP_CLIENT_IP");
else if (getenv("REMOTE_ADDR"))
$ip = getenv("REMOTE_ADDR");
else
$ip = "Unknown";
return $ip;
}
?>
<?php
$badIp = "127.0.0.1|202.102.*.*|129.125.24.*";
$currentIp = GetIP(); //GetIp()函数返回的是获取当前访问者的ip
$ips = explode("|",$ips);
$a=explode("|",$badIp); //得到坏ip;数组
// print_r($a)."<br>";
$b=explode(".",$currentIp); //当前用户的ip;
// print_r($b);
for($i=0;$i<count($a);$i++)
{ $c=explode(".",$a[$i]); //分解出坏ip。。
// print_r($c);
for($j=0;$j<count($c[$i]);$j++) //用.分割出的坏ip循环
{
// echo "<br>".$c[2]."and".$c[3]."<br>";
if($c[2]=="*" and $c[3]=="*") // 202.102.*.* //则禁用所有202.102开头的ip地址
{
if($b[0]==$c[0] and $b[1]==$c[1])
{
echo $currentIp."坏ip"."<br>";
exit;
}
}
else if($b[0]==$c[0] and $b[1]==$c[1] and $b[2]==$c[2] and $b[3]==$c[3]) //127.0.0.1//则禁用127.0.0.1的ip地址
{
echo $currentIp."坏ip"."<br>";
exit;
}
else if($c[3]=="*") // 29.125.24.*" //则禁用所有29.125.24开头的ip地址
{
if($b[0]==$c[0] and $b[1]==$c[1] and $b[2]==$c[2])
{
echo $currentIp."坏ip"."<br>";
exit;
}
} }
}function GetIP() { //获取IP
if ($_SERVER["HTTP_X_FORWARDED_FOR"])
$ip = $_SERVER["HTTP_X_FORWARDED_FOR"];
else if ($_SERVER["HTTP_CLIENT_IP"])
//OsPHP.COM.CN
$ip = $_SERVER["HTTP_CLIENT_IP"];
else if ($_SERVER["REMOTE_ADDR"])
$ip = $_SERVER["REMOTE_ADDR"];
else if (getenv("HTTP_X_FORWARDED_FOR"))
//oSPHP.COM.CN
$ip = getenv("HTTP_X_FORWARDED_FOR");
else if (getenv("HTTP_CLIENT_IP"))
$ip = getenv("HTTP_CLIENT_IP");
else if (getenv("REMOTE_ADDR"))
$ip = getenv("REMOTE_ADDR");
else
$ip = "Unknown";
return $ip;
}
?>
===================
$badIp = "127.0.0.1|202.102.*.*|129.125.24.*|202.*.122.233|202.111.*.201|192.*.233.*|*.168.234.133";
function noAllowIps($currentIp)
{
global $badIp;
$ips = explode('.',$currentIp);
//$r = array_map(create_function('$a','if(!is_numeric($a)||$a>255||$a<=0) return 0;else return $a;'),$ips);
foreach($ips as $v)
{
if(!is_numeric($v) || $v>255 || $v<=0 ) return 'not allow';
}
/*
我想在这里实现,把得到的访问者的ip和系统设计的禁用的ip($badIp)进行比较,
如果当前ip在系统禁用的ip之内则返回false,如果没有*号能配符我倒可以写,加了通配符我就不会写了。
127.0.0.1//则禁用127.0.0.1的ip地址
202.102.*.* //则禁用所有202.102开头的ip地址
29.125.24.*" //则禁用所有29.125.24开头的ip地址
*/ $mc = array("."=>"\.","*"=>"([0-9]+)");
$s = strtr($badIp,$mc);
return preg_match("/{$s}/",$currentIp,$m) ? 'allow' : 'not allow';} echo noAllowIps('192.2.233.3');
$s = strtr($badIp,$mc);
//这句话不是很理解,请指教
function noAllowIps($ips)
{
global $badIp;
$currentIp = GetIp(); //GetIp()函数返回的是获取当前访问者的ip
$ips = explode("|",$badIp); foreach( $ips as $v )
{
if ( strcmp( $v, substr( $currentIp, 0, strlen($v) ) ) == 0 )
{
return false;
}
} return true;
}
?>
手册:
======
例子 2. strtr() example with two arguments<?php
$trans = array("hello" => "hi", "hi" => "hello");
echo strtr("hi all, I said hello", $trans);
?> This will show: hello all, I said hi
function noAllowIps()
{
global $badIp;
$currentIp = $_SERVER["REMOTE_ADDR"]; //GetIp()函数返回的是获取当前访问者的ip
$ips = explode("|",$badIp); foreach( $ips as $v )
{
if ( strcmp( $v, substr( $currentIp, 0, strlen($v) ) ) == 0 )
{
return false;
}
} return true;
} echo noAllowIps();
?>
$badIp = "127.0.0.1|202.102.*.*|129.125.24.*|192.168.*.183";
function noAllowIps()
{
global $badIp;
$currentIp = $_SERVER["REMOTE_ADDR"]; //GetIp()函数返回的是获取当前访问者的ip
$ips = explode("|",$badIp); foreach( $ips as $v )
{
$v = "/^".str_replace(".*", ".[0-9]+", $v)."$/";
if ( preg_match( $v, $currentIp ) == 1 )
{
return false;
}
} return true;
}
echo noAllowIps();
?>
$badIp = "127.0.0.1|202.102.*.*|129.125.24.*";
$badIp = explode('|', str_replace('*', '0', $badIp));$ip = '202.102.0.1';foreach($badIp as $mask) {
if(sonnet($ip, $mask) == $mask) echo 0;
}1、应使用网段的概念,而非通配符概念2、函数sonnet代码
/**
* 返回ip按指定掩码的网段地址
**/
if(! function_exists('sonnet')):
function sonnet($ip, $mask=22) {
$ip = preg_replace("/(^|\.)0+(\d+)/", "$1$2", $ip);
if(long2ip(ip2long($ip)) != $ip) return '';
if(is_numeric($mask)) {
$mask = bindec(str_pad(decbin(pow(2, $mask)-1), 32, '0'));
}else {
$mask = ip2long($mask);
}
return long2ip(ip2long($ip) & $mask);
}
endif;
$badIp = "127.0.0.1|202.102.*.*|129.125.24.*|192.168.*.183";
function noAllowIps()
{
global $badIp;
$currentIp = $_SERVER["REMOTE_ADDR"]; //GetIp()函数返回的是获取当前访问者的ip
$badIp = "/".str_replace("*", "(\\d+)", $badIp)."/"; if ( preg_match( $badIp, $currentIp ) == 1 ) return false; return true;
}
echo noAllowIps();
?>你自己的方法也行,一次全replace,然后再匹配
2、ip2long 转化为 A 3395682304,B 3395747839 (Php好像转的有问题,我用我的Java工具类转的)。
3、比对 202.102.5.7/C 3395683591 。 C 3395683591 > A 3395682304,C 3395683591 < B 3395747839 。
结论202.102.5.7匹配202.102.*.* 。关于2可以看一下xuzuning转的方式。
待会儿我提供下分段比较。
$badIp = explode('|', str_replace('*', '0', $badIp)); $ip = '202.102.1.1'; foreach($badIp as $mask) {
echo $mask."\n<BR>";
if(sonnet($ip, $mask) == $mask) echo 0;
}这个结果就是错误的了!
<?php
/**
* -_-#
* @param String $ipRange
* @param String $ip
* @return boolean
*/
function isSub($ipRange,$ip) {
$ipStrs = explode('.',$ip);
$ipRangeStrs = explode('.',$ipRange);
$isSub = (count($ipStrs) == count($ipRangeStrs)); //
$isSub = $isSub == 4;
$cRange = 0;
if ($isSub) {
for ($i = 0; $i < 4; $i++) {
$cRange = $ipRangeStrs[$i];
if ($cRange =='*') {
$isSub &= true;
break;
}else if ($cRange == $ipStrs[$i]) {
$isSub &= true;
}else {
$isSub &= false;
}
}
}
return $isSub;
}
$ip = '202.102.5.7';
$ipRange = '202.102.*.*';
var_export(isSub($ipRange,$ip)); // true
$ip = '202.103.5.7';
var_export(isSub($ipRange,$ip)); // false
$ip = '202.101.5.7';
var_export(isSub($ipRange,$ip)); // false
?>
不过我觉得在这里逐字符对比效率应该会高一些。
你自己测试一下。2楼的思路是对的。
ip[0]*256*256*256+ip[1]*256*256+ip[2]*256+ip[3]
这是ip2long的公式。
function ip2long6($ip){
if (substr_count($ip, '::')){
$ip = str_replace('::', str_repeat(':0000', 8 - substr_count($ip, ':')) . ':', $ip) ;
}
$ip = explode(':', $ip) ;
$r_ip = '' ;
foreach ($ip as $v){
$r_ip .= str_pad(base_convert($v, 16, 2), 16, 0, STR_PAD_LEFT) ;
}
return base_convert($r_ip, 2, 10) ;
}
Ipv6的转换函数,手册里的,正误自鉴。
<?php
$banipList = '127.0.0.1|202.102.*.*|129.125.24.*';
function isBanip($banipList,$ip){
$isban = false;
$isban = strrpos($banipList,$ip) > -1;
if (!$isban){
$i = 3;
$ips = explode('.',$ip);
do{
if ($i < 0){
break;
}
$ips[$i] = '*';
$isban = strrpos($banipList,implode('.',$ips)) > -1;
if ($isban){
break;
}
$i--;
}while(true);
}
return $isban;
}
$ip = '202.102.5.7';
$ipRange = '202.102.*.*';
var_export(isBanip($ipRange,$ip)); // true
$ip = '202.103.5.7';
var_export(isBanip($ipRange,$ip)); // false
$ip = '202.101.5.7';
var_export(isBanip($ipRange,$ip)); // false$ip ='127.0.0.1';
$start = microtime(true);
for($i=0;$i<10000;$i++){
isBanip($banipList,$ip);
}
echo microtime(true) - $start;// 按字符
// 100,000
// 6.7096321582794s
// 6.8487989902496s
// 按网段
// 10,000
// 5.603569984436s
?>
效率差得远,理论是按网段算,但具体问题还是得具体对待。
$badIp = "127.0.0.1|202.102.*.*|129.125.24.*";
$badips = explode("|",$badIp);
$regbadips = array();
foreach($badips as $ip) {
$ip = str_replace('.', '\\.', $ip);
$ip = str_replace('*', '.*', $ip);
array_push($regbadips, $ip);
}
function noAllowIp($ip, $ip_set) {
foreach($ip_set as $i) {
if (preg_match("/$i/", $ip)) {
echo "match: ".$i.", "; return '1';
}
}
return '0';
}
$testips = array('202.102.0.1', '127.0.0.1', '129.125.2*.*');
foreach($testips as $i) {
echo $i.": ";
echo "[".noAllowIp($i, $regbadips)."]<br>";
}
?>
{
$e = explode("/", $n);
if (!$e[1]) $e[1] = 32;
$_nIp = ip2long($e[0]);
if (!$_nIp or $_nIp === -1) return false; //ip地址格式错误 $_base = str_pad("", $e[1], '1');
$_Mask = str_pad($_base, 32, '0'); $__Mask = bindec($_Mask); $__ip = ip2long($ip); return decbin($_nIp & $__Mask) === decbin($__ip & $__Mask) ? 1 : 0;
} if (checkIpInNetwork("202.102.0.1/24", "202.102.123.1"))
{
echo "ip:202.102.123.1 在网络 202.102.0.1/24 中<BR>";
}
else
{
echo "ip:202.102.123.1 不在网络 202.102.0.1/24 中<BR>";
} if (checkIpInNetwork("202.102.0.1/16", "202.102.123.1"))
{
echo "ip:202.102.123.1 在网络 202.102.0.1/16 中<BR>";
}
else
{
echo "ip:202.102.123.1 不在网络 202.102.0.1/16 中<BR>";
} if (checkIpInNetwork("202.102.0.1", "202.102.123.1"))
{
echo "ip:202.102.123.1 在网络 202.102.0.1 中<BR>";
}
else
{
echo "ip:202.102.123.1 不在网络 202.102.0.1 中<BR>";
} if (checkIpInNetwork("202.102.0.1", "202.102.0.1"))
{
echo "ip:202.102.0.1 在网络 202.102.0.1 中<BR>";
}
else
{
echo "ip:202.102.123.1 不在网络 202.102.0.1/16 中<BR>";
}显示结果:ip:202.102.123.1 不在网络 202.102.0.1/24 中
ip:202.102.123.1 在网络 202.102.0.1/16 中
ip:202.102.123.1 不在网络 202.102.0.1 中
ip:202.102.0.1 在网络 202.102.0.1 中
$badIp = "127.*.*.*|202.*.*.*|129.*.24.*|192.168.12.183"; $current = "192.168.112.183"; //@$ips--为比对的模版字符串;
//@$cur--为比对的对象;
//返回值为布尔类型;
//该函数只适合ipv4
function check(&$ips , $cur){ $ary_ips = explode("|",$ips); $mod = explode('.',$cur); //设置标签--当该标签最后等于4时返回真
$flag; //与模版中的每一组对象进行比对;
foreach($ary_ips as $val){ $flag = 0 ; $temp = explode('.',$val); if($temp[0] == '*'){//比较第一个字节
$flag++;
}else if($mod[0] == $temp[0]){
$flag++;
}else{
continue;
}
if($temp[1] == '*'){//比较第二个字节
$flag++;
}else if($mod[1] == $temp[1]){
$flag++;
}else{
continue;
} if($temp[2] == '*'){//比较第三个字节
$flag++;
}else if($mod[2] == $temp[2]){
$flag++;
}else{
continue;
} if($temp[3] == '*'){//比较第四个字节
$flag++;
}else if($mod[3] == $temp[3]){
$flag++;
}else{
continue;
} if($flag == 4){
return true;
}else{
continue;
}
}
return false;
}
//以下测试php效率
$begin = microtime(true);
for($i = 0 ; $i < 100000 ; $i++){ $testip = rand(127 , 254) . ".".rand(1 , 254). ".".rand(1 , 254). ".".rand(1 , 254); // echo "$i--", $testip , " : <font color=" ,check($badIp,$testip) ? "red>yes" : "blue>no" , "</font><br>";
} $end = microtime(true); echo $end - $begin , "秒";
?>
$ipList = explode("|", $ips);
for ($i = 0; $i < count($ipList); $i++)
{
$ep = explode("/", $n);
$_Ep[$i][0] = $ep[0];
$_Ep[$i][1] = is_numeric($ep[1])?$ep[1]:32; $_base = str_pad("", $ep[1], '1');
$_Mask = str_pad($_base, 32, '0');
$_Ep[$i][2] = bindec($_Mask); $_Ep[$i][3] = ip2long($ep[0]);
}function checkIpsInNetwork($n, $ips)
{
$result = false;
for ($i = 0; $i < count($n); $i++)
{
if (checkIpInNetwork($n[$i], $ips[$i])) $result = true;
}
return $result;
}function checkIpInNetwork($n, $ip)
{
if (!is_array($n)) return false;
$_nIp = ip2long($n[0]);
if (!$_nIp or $_nIp === -1) return false; //ip地址格式错误 return decbin($_nIp & $n[2]) === decbin($n[3] & $n[2]) ? 1 : 0;
}
$start = microtime(true);for($i = 0; $i < 100000; $i++)
{
$testip = rand(0 , 255) . ".".rand(0 , 255). ".".rand(0 , 255). ".".rand(0 , 255);
checkIpsInNetwork($_Ep, $testip);
}echo microtime(true) - $start;
看看谁的简洁$badIp = "127.0.0.1|202.102.*.*|129.125.24.*";
$badIp = explode('|', str_replace('*', '[0-9]+', $badIp)); $ips = array(
"127.0.0.1",
"202.102.1.2",
"202.103.0.2",
"129.125.23.2",
'202.102.0.1',
'220.10.0.1',
);
foreach($ips as $ip) {
foreach($badIp as $net) {
if(ereg($net, $ip)) //如果应该被禁用则打印
echo "$ip : $net<br />";
}
}