ホームページ >バックエンド開発 >PHPチュートリアル >PHPでip2cidrを実装する方法(複数のcidrを生成)
1.120.0.0 1.159.255.255 1.120.0.0/13 1.128.0.0/11 などの複数の cidr を生成する関数はありますか
function ip2cidr ($ip_start ,$ ip_end ) {
if(long2ip(ip2long($ip_start))!=$ip_start または long2ip(ip2long($ip_end))!=$ip_end) return NULL;
$ipl_start=(int)ip2long($ip_start); ipl_end =(int)ip2long($ip_end);
if($ipl_start>0 && $ipl_end $delta=$ipl_end-$ipl_start; netmask =str_pad(decbin($delta),32,"0","STR_PAD_LEFT");
if(ip2long($ip_start)==0 && substr_count($netmask,"1")==32) return "0.0. 0.0 /0";
if($delta0 && $delta%2==0)) return NULL;
for($mask=0;$mask if(substr_count($netmask,"0")!=$mask) return NULL;
return "$ip_start/$mask" } この関数は複数の CID を生成できません
echo ip2cidr('1.120.0.0', '1.127.255.255'); //1.120.0.0/13function ip2cidr($ip_start,$ip_end) { if(long2ip(ip2long($ip_start))!=$ip_start or long2ip(ip2long($ip_end))!=$ip_end) return NULL; $ipl_start = ip2long($ip_start); $ipl_end = ip2long($ip_end); if($ipl_start>0 && $ipl_end<0) $delta = ($ipl_end + 4294967296) - $ipl_start; else $delta = $ipl_end - $ipl_start; $netmask = str_pad(decbin($delta), 32, "0", STR_PAD_LEFT); if(ip2long($ip_start)==0 && substr_count($netmask,"1")==32) return "0.0.0.0/0"; if($delta<0 or ($delta>0 && $delta%2==0)) return NULL; for($mask=0; $mask<32; $mask++) if($netmask[$mask]==1) break; if(substr_count($netmask,"0")!=$mask) return NULL; return "$ip_start/$mask";}
echo ip2cidr('1.120.0.0', '1.127.255.255'); //1.120.0.0/13function ip2cidr($ip_start,$ip_end) { if(long2ip(ip2long($ip_start))!=$ip_start or long2ip(ip2long($ip_end))!=$ip_end) return NULL; $ipl_start = ip2long($ip_start); $ipl_end = ip2long($ip_end); if($ipl_start>0 && $ipl_end<0) $delta = ($ipl_end + 4294967296) - $ipl_start; else $delta = $ipl_end - $ipl_start; $netmask = str_pad(decbin($delta), 32, "0", STR_PAD_LEFT); if(ip2long($ip_start)==0 && substr_count($netmask,"1")==32) return "0.0.0.0/0"; if($delta<0 or ($delta>0 && $delta%2==0)) return NULL; for($mask=0; $mask<32; $mask++) if($netmask[$mask]==1) break; if(substr_count($netmask,"0")!=$mask) return NULL; return "$ip_start/$mask";}
モデレータ、あなたが書いたことは2階の私のものと同じです
分割はそれほど難しいことではありませんが、IP範囲1.120.0.0 1.159.255.255でCIDRを生成する問題は解決できません。 、分割はどうやって決めるのですか?
例: echo ip2cidr('1.120.0.0', '1.127.255.255') //1.120.0.0/13 echo ip2cidr('1.120.0.0', '1.151.255.255') //1.120.0.0/11
echo ip2cidr('1.152.0.0', '1.159.255.255'); .0.0/13
別の逆アセンブル方法
そして
echo ip2cidr('1.120.0.0', '1.159.255.255')
失敗の理由は、マスクが
000000000010011111111111111111 であるためです。 11
実際、何も問題はありませんそれは、cidr は単なる表現のためのものではありません
注意してください
echo long2ip(bindec('111111111111111111111')+ip2long('1.120.0.0')); したがって、2 番目の逆アセンブリメソッドは次のことができます。機械で実現するのと、最初は手動でしか実現できないようです
分割はそれほど難しくありませんが、分割点はどうやって決めるのでしょうか?
例: echo ip2cidr('1.120.0.0', '1.127.255.255') //1.120.0.0/13
echo ip2cidr('1.128.0.0', '1.159.255.255'); 11
は逆アセンブリメソッドです
echo ip2cidr('1.152.0.0', '1.159.255.255'); .0.0/13
別の逆アセンブル方法
そして
echo ip2cidr('1.120.0.0', '1.159.255.255')
失敗の理由は、マスクが
000000000010011111111111111111 であるためです。 11
実際、何も悪いことはありませんそれは、cidr は単なる表現のためのものではありません
注意してください
echo long2ip(bindec('111111111111111111111')+ip2long('1.120.0.0')); したがって、2 番目の逆アセンブリメソッドは次のことができます。機械で実現するのと、最初は手動でしか実現できないようです
モデレーターありがとうございます
ip2cidr("1.40.0.0","1.44.255.255")
000000000000010011111111111111
echo long2ip(bindec('11111 1111111111111111')+ip2long(' 1.40.0.0')); //1.71.255.255 は指定された IP の範囲を超えています
0000000000000100 1111111111111111
こんな感じです
ありがとうございます あなたと私がそれを探索します
把问题多分析一下
00000001011101110000000000000000 1.119.0.0
00000001011110000000000000000000 1.120.0.0
00000001011110010000000000000000 1.121.0.0
00000001011110100000000000000000 1.122.0.0
00000001011110110000000000000000 1.123.0.0
00000001011111000000000000000000 1.124.0.0
00000001011111010000000000000000 1.125.0.0
00000001011111100000000000000000 1.126.0.0
00000001011111110000000000000000 1.127.0.0
00000001100000000000000000000000 1.128.0.0
00000001100000010000000000000000 1.129.0.0
00000001100000100000000000000000 1.130.0.0
00000001100000110000000000000000 1.131.0.0
00000001100001000000000000000000 1.132.0.0
00000001100001010000000000000000 1.133.0.0
00000001100001100000000000000000 1.134.0.0
00000001100001110000000000000000 1.135.0.0
00000001100010000000000000000000 1.136.0.0
00000001100010010000000000000000 1.137.0.0
00000001100010100000000000000000 1.138.0.0
00000001100010110000000000000000 1.139.0.0
00000001100011000000000000000000 1.140.0.0
00000001100011010000000000000000 1.141.0.0
00000001100011100000000000000000 1.142.0.0
00000001100011110000000000000000 1.143.0.0
00000001100100000000000000000000 1.144.0.0
00000001100100010000000000000000 1.145.0.0
00000001100100100000000000000000 1.146.0.0
00000001100100110000000000000000 1.147.0.0
00000001100101000000000000000000 1.148.0.0
00000001100101010000000000000000 1.149.0.0
00000001100101100000000000000000 1.150.0.0
00000001100101110000000000000000 1.151.0.0
00000001100110000000000000000000 1.152.0.0
00000001100110010000000000000000 1.153.0.0
00000001100110100000000000000000 1.154.0.0
00000001100110110000000000000000 1.155.0.0
00000001100111000000000000000000 1.156.0.0
00000001100111010000000000000000 1.157.0.0
00000001100111100000000000000000 1.158.0.0
00000001100111110000000000000000 1.159.0.0
00000001101000000000000000000000 1.160.0.0
结束
echo ip2cidr('1.120.0.0', '1.159.255.255'), PHP_EOL;echo ip2cidr('1.120.0.0', '1.169.255.255'), PHP_EOL;echo ip2cidr('1.120.0.0', '1.179.255.255'), PHP_EOL;function ip2cidr($ip_start,$ip_end) { if(long2ip(ip2long($ip_start))!=$ip_start or long2ip(ip2long($ip_end))!=$ip_end) return !trigger_error('ip 不合法', E_USER_NOTICE); $ipl_start = ip2long($ip_start); $ipl_end = ip2long($ip_end); if($ipl_start>0 && $ipl_end<0) $delta = ($ipl_end + 4294967296) - $ipl_start; else $delta = $ipl_end - $ipl_start; $netmask = sprintf('%032b', $delta); if(ip2long($ip_start)==0 && substr_count($netmask,"1")==32) return "0.0.0.0/0"; if($delta<0 or ($delta>0 && $delta%2==0)) return !trigger_error("区间数量不合法 $delta", E_USER_NOTICE); for($mask=0; $mask<32; $mask++) if($netmask[$mask]==1) break; if(substr_count($netmask,"0")!=$mask) { $w = strrpos($netmask, '0') + 1; $m = pow(2, 32-$w) - 1; $ip_start = long2ip(($ipl_start & ~$m)+$m+1); return long2ip($ipl_start & ~$m) . "/$w," . ip2cidr($ip_start,$ip_end); }; return "$ip_start/$mask";}1.120.0.0/13,1.128.0.0/11
谢谢版主大人 尤其认识到自身不足 还要好好努力啊