How PHP implements ip2cidr (multiple cidr are generated)

Source: Internet
Author: User
How does PHP implement ip2cidr (generate multiple cidr)? are there any functions that generate multiple cidr, for example, 1.120.0.0 1.159.255.255 to generate 1.120.0.0/13 1.128.0.0/11?


Reply to discussion (solution)

Function ip2cidr ($ ip_start, $ ip_end ){
If (long2ip (ip2long ($ ip_start ))! = $ Ip_start or 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 <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 ";
} This function cannot generate multiple cidr instances.

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";} 


The moderator, as you wrote on the second floor, cannot solve the problem of CIDR generation in the IP address range 1.120.0.0 1.159.255.255.

Although splitting is not very difficult, how do you determine the splitting point?
For example
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'); // 1.128.0.0/11
Is a split method
Echo ip2cidr ('1. 120.0.0 ', '1. 151.20.255'); // 1.120.0.0/11
Echo ip2cidr ('1. 152.0.0 ', '1. 159.255.255'); // 1.152.0.0/13
Another method of splitting

While
Echo ip2cidr ('1. 120.0.0 ', '1. 159.255.255 ');
The reason for the failure is that the mask is
00000000001001111111111111111111
In fact, there is nothing wrong with it, but it cannot be expressed by cidr.

Notes
Echo long2ip (bindec ('20140901') + ip2long ('1. 120.0.0 '); // 1.151.255.255
Therefore, the second split method can be implemented by machines, while the first method can only be implemented manually.

Although splitting is not very difficult, how do you determine the splitting point?
For example
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'); // 1.128.0.0/11
Is a split method
Echo ip2cidr ('1. 120.0.0 ', '1. 151.20.255'); // 1.120.0.0/11
Echo ip2cidr ('1. 152.0.0 ', '1. 159.255.255'); // 1.152.0.0/13
Another method of splitting

While
Echo ip2cidr ('1. 120.0.0 ', '1. 159.255.255 ');
The reason for the failure is that the mask is
00000000001001111111111111111111
In fact, there is nothing wrong with it, but it cannot be expressed by cidr.

Notes
Echo long2ip (bindec ('20140901') + ip2long ('1. 120.0.0 '); // 1.151.255.255
Therefore, the second split method can be implemented by machines, while the first method can only be implemented manually.

Thank you, moderator.

Ip2cidr ("1.40.0.0", "1.44.255.255 ");
00000000000001001111111111111111
Echo long2ip (bindec ('200') + ip2long ('1. 40.0.0 '); // 1.71.255.255 exceeds the specified IP address range

0000000000000100 1111111111111111
To obtain

Splitting should start from a small area
This is a big part. it is definitely not suitable.

Thank you for your exploration.

Analyze more problems
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

End

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 illegal ', E_USER_NOTICE); $ ipl_start = ip2long ($ ip_start); $ ipl_end = ip2long ($ ip_end ); if ($ ipl_start> 0 & amp; $ 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 ("The number of intervals is invalid $ 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

Thank you! the moderator is particularly aware of his own shortcomings and has to work hard.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.