Konwertery adresow ip w postaci: AAA.BBB.CCC.DDD, integer i binary do kazdej innej formy + sprawdzanie czy IP nalezy do danej sieci/maska.
  1. <?php
  2. /**
  3.  * Basic operations on IP addresses
  4.  * - conversions from (IP, decimal, binary) to (IP, decimal, binary)
  5.  * - checking whether IP is in specified network
  6.  *
  7.  * @author dr_bonzo
  8.  * @version 0.1
  9.  */
  10. class Ip_Manipulator
  11. {
  12. /**
  13.  * Indicates whether $sIp_address is in $sNetwork_address/$sNetmask network
  14.  *
  15.  * @param string $sIp_address
  16.  * @param string $sNetwork_address
  17.  * @param string $sNetmask
  18.  *
  19.  * @return bool
  20.  * @throws Exception On wrong addresses
  21.  */
  22. static public function ipIsInNetwork( $sIp_address, $sNetwork_address, $sNetmask )
  23. {
  24. if ( ! self::ipAddressIsValid( $sIp_address ) )
  25. {
  26. throw new Exception( 'Invalid IP address (' . $sIp_address . ')' );
  27. }
  28.  
  29. if ( ! self::networkIsValid( $sNetwork_address ) )
  30. {
  31. throw new Exception( 'Invalid network address (' . $sNetwork_address . ')' );
  32. }
  33.  
  34. if ( ! self::netmaskIsValid( $sNetmask ) )
  35. {
  36. throw new Exception( 'Invalid Netmask (' . $sNetmask . ')' );
  37. }
  38.  
  39. $iIp_address_dec = self::ipToDec( $sIp_address );
  40. $sIp_address_bin = self::decToBin( $iIp_address_dec );
  41.  
  42. $iNetwork_address_dec = self::ipToDec( $sNetwork_address );
  43. $sNetwork_address_bin = self::decToBin( $iNetwork_address_dec );
  44.  
  45. if ( preg_match( &#092;"/^d{1,2}$/\", $sNetmask ) === 1 )
  46. {
  47. $sNetmask_bin = str_repeat( '1', intval( $sNetmask ) ) . str_repeat( '0', 32 - intval( $sNetmask ) );
  48. $iNetmask_dec = bindec( $sNetmask_bin );
  49. }
  50. else
  51. {
  52. $iNetmask_dec = self::ipToDec( $sNetmask );
  53. $sNetmask_bin = self::decToBin( $iNetmask_dec );
  54. }
  55.  
  56. $sIp_n_netmask_combined = self::decToBin( $iIp_address_dec & $iNetmask_dec );
  57.  
  58. return ( $sIp_n_netmask_combined === $sNetwork_address_bin );
  59. }
  60.  
  61. /**
  62.  * Indicates whether IP address is valid
  63.  *
  64.  * @param string $sIp_address
  65.  * @return bool Whether ip is valid
  66.  */
  67. static private function ipAddressIsValid( $sIp_address )
  68. {
  69. return ( preg_match( &#092;"/^d{1,3}(.d{1,3}){3}$/\", $sIp_address ) === 1 );
  70. }
  71.  
  72. /**
  73.  * Indicates whether network address is valid
  74.  *
  75.  * @param string $sNetwork_address
  76.  * @return bool
  77.  */
  78. static private function networkIsValid( $sNetwork_address )
  79. {
  80. return ( preg_match( &#092;"/^d{1,3}(.d{1,3}){3}$/\", $sNetwork_address ) === 1 );
  81. }
  82.  
  83. /**
  84.  * Indicates whether mask is valid
  85.  *
  86.  * @param string $sNetmask
  87.  * @return bool
  88.  */
  89. static private function netmaskIsValid( $sNetmask )
  90. {
  91. return ( preg_match( &#092;"/(^d{1,3}(.d{1,3}){3}$|d{1,2})/\", $sNetmask ) === 1 );
  92. }
  93.  
  94. /**
  95.  * Converts IP address (aaa.bbb.ccc.ddd) to decimal number
  96.  * (float type, because address can be > 2E9 -- that means negative integer)
  97.  *
  98.  * @param string $sIp
  99.  * @return float Ip address
  100.  */
  101. static public function ipToDec( $sIp )
  102. {
  103. $aIp = explode( '.', $sIp );
  104. $fIp = 0;
  105.  
  106. for ( $i = 0; $i < 4; $i++ )
  107. {
  108. $fIp = $fIp * 256 + intval( $aIp[ $i ] );
  109. }
  110.  
  111. return floatval( $fIp );
  112. }
  113.  
  114. /**
  115.  * Converts IP address (aaa.bbb.ccc.ddd) to binary number
  116.  *
  117.  * @param string $sIp
  118.  * @return string
  119.  */
  120. static public function ipToBin( $sIp )
  121. {
  122. $fIp = self::ipToDec( $sIp );
  123. $sIp_bin = decbin( $fIp );
  124. $sIp_bin = str_repeat( '0', 32 - strlen( $sIp_bin ) ) . $sIp_bin;
  125.  
  126. return $sIp_bin;
  127. }
  128.  
  129. /**
  130.  * Converts decimal representation of IP address to IP address (aaa.bbb.ccc.ddd)
  131.  *
  132.  * @param float $fIp
  133.  * @return string
  134.  */
  135. static public function decToIp( $fIp )
  136. {
  137. $sIp = '';
  138.  
  139. for ( $i = 0; $i < 4; $i++ )
  140. {
  141. $sIp = '.' . ( ( $fIp % 256 + 256 ) % 256 ) . $sIp;
  142. $fIp = floor( $fIp / 256 );
  143. }
  144.  
  145. return substr( $sIp, 1 );
  146. }
  147.  
  148. /**
  149.  * Converts decimal representation of IP address to binary repr.
  150.  *
  151.  * @param float $fIp
  152.  * @return string
  153.  */
  154. static public function decToBin( $fIp )
  155. {
  156. $sIp_bin = decbin( $fIp );
  157. $sIp_bin = str_repeat( '0', 32 - strlen( $sIp_bin ) ) . $sIp_bin;
  158.  
  159. return $sIp_bin;
  160. }
  161.  
  162. /**
  163.  * Converts binary representation of IP address to its decmal repr.
  164.  *
  165.  * @param string $sIp_bin
  166.  * @return float
  167.  */
  168. static public function binToDec( $sIp_bin )
  169. {
  170. return floatval( bindec( $sIp_bin ) );
  171. }
  172.  
  173. /**
  174.  * Converts binary representation of IP address to IP address (aaa.bbb.ccc.ddd)
  175.  *
  176.  * @param string $sIp_bin
  177.  * @return string
  178.  */
  179. static public function binToIp( $sIp_bin )
  180. {
  181. $sIp = self::decToIp( self::binToDec( $sIp_bin ) );
  182.  
  183. return floatval( $sIp );
  184. }
  185. }
  186.  
  187. /*** USAGE ***/
  188.  
  189. try
  190. {
  191. print( ( Ip_Manipulator::ipIsInNetwork( '172.17.1.3', '172.16.0.0', '15' ) ? 'Nalezy do sieci' : 'Nie nalezy do sieci' ) . '<br />' );
  192. print( ( Ip_Manipulator::ipIsInNetwork( '192.168.1.3', '192.168.13.0', '255.255.255.0' ) ? 'Nalezy do sieci' : 'Nie nalezy do sieci' ) . '<br />' );
  193. print( &#092;"<hr />IP = '192.168.1.3'<br />\" );
  194.  
  195. print( 'IP -> integer: ' . Ip_Manipulator::ipToDec( '192.168.1.3' ) . '<br />' );
  196. print( 'IP -> binary: ' . Ip_Manipulator::ipToBin( '192.168.1.3' ) . '<br />' );
  197.  
  198. print( &#092;"<hr />IP = 3232235779<br />\" );
  199.  
  200. print( 'integer -> IP: ' . Ip_Manipulator::decToIp( 3232235779 ) . '<br />' );
  201. print( 'integer -> binary: ' . Ip_Manipulator::decToBin( 3232235779 ) . '<br />' );
  202.  
  203. print( &#092;"<hr />IP = '11000000101010000000000100000011'<br />\" );
  204.  
  205. print( 'binary -> integer: ' . Ip_Manipulator::binToDec( '11000000101010000000000100000011' ) . '<br />' );
  206. print( 'binary -> IP: ' . Ip_Manipulator::binToIp( '11000000101010000000000100000011' ) . '<br />' );
  207. }
  208. catch ( Exception $eException )
  209. {
  210. print( 'ERROR: ' . $eException->getMessage() );
  211. }
  212.  
  213. ?>


PS. Przypomne ze MySQL ma szybsza funkcje INET_ATON() i INET_NTOA() do konwersji IP <-> integer.