ホームページ >バックエンド開発 >PHPチュートリアル >PHPでip2cidrを実装する方法(複数のcidrを生成)

PHPでip2cidrを実装する方法(複数のcidrを生成)

WBOY
WBOYオリジナル
2016-06-23 13:52:081474ブラウズ

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.128.0.0', '1.159.255.255'); 11 は逆アセンブリメソッドです

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.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 番目の逆アセンブリメソッドは次のことができます。機械で実現するのと、最初は手動でしか実現できないようです
モデレーターありがとうございます
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
1.120.0.0/15,1.112.0.0/12,1.128.0.0/15,1.128.0.0/13,1.136.0.0/15,1.138.0.0/11
1.120.0.0/14,1.120.0.0/13,1.128.0.0/14,1.128.0.0/12,1.144.0.0/14,1.148.0.0/11

谢谢版主大人 尤其认识到自身不足 还要好好努力啊

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。