public static function toHex( $ip ) {
if ( self::isIPv6( $ip ) ) {
$n = 'v6-' . self::IPv6ToRawHex( $ip );
- } else {
- $n = self::toUnsigned( $ip );
+ } elseif ( self::isIPv4( $ip ) ) {
+ // Bug 60035: an IP with leading 0's fails in ip2long sometimes (e.g. *.08)
+ $ip = preg_replace( '/(?<=\.)0+(?=[1-9])/', '', $ip );
+ $n = ip2long( $ip );
+ if ( $n < 0 ) {
+ $n += pow( 2, 32 );
+ # On 32-bit platforms (and on Windows), 2^32 does not fit into an int,
+ # so $n becomes a float. We convert it to string instead.
+ if ( is_float( $n ) ) {
+ $n = (string)$n;
+ }
+ }
if ( $n !== false ) {
- $n = wfBaseConvert( $n, 10, 16, 8, false );
+ # Floating points can handle the conversion; faster than wfBaseConvert()
+ $n = strtoupper( str_pad( base_convert( $n, 10, 16 ), 8, '0', STR_PAD_LEFT ) );
}
+ } else {
+ $n = false;
}
return $n;
return $r_ip;
}
- /**
- * Given an IP address in dotted-quad/octet notation, returns an unsigned integer.
- * Like ip2long() except that it actually works and has a consistent error return value.
- *
- * @param string $ip quad dotted IP address.
- * @return Mixed: string/int/false
- */
- public static function toUnsigned( $ip ) {
- if ( self::isIPv6( $ip ) ) {
- $n = wfBaseConvert( self::IPv6ToRawHex( $ip ), 16, 10 );
- } else {
- // Bug 60035: an IP with leading 0's fails in ip2long sometimes (e.g. *.08)
- $ip = preg_replace( '/(?<=\.)0+(?=[1-9])/', '', $ip );
- $n = ip2long( $ip );
- if ( $n < 0 ) {
- $n += pow( 2, 32 );
- # On 32-bit platforms (and on Windows), 2^32 does not fit into an int,
- # so $n becomes a float. We convert it to string instead.
- if ( is_float( $n ) ) {
- $n = (string)$n;
- }
- }
- }
-
- return $n;
- }
-
/**
* Convert a network specification in CIDR notation
* to an integer network and a number of bits
$start = "v6-$start";
$end = "v6-$end";
}
- // Explicit range notation...
+ // Explicit range notation...
} elseif ( strpos( $range, '-' ) !== false ) {
list( $start, $end ) = array_map( 'trim', explode( '-', $range, 2 ) );
$start = self::toHex( $start );
$this->assertNull( IP::sanitizeIP( ' ' ) );
}
- /**
- * @covers IP::toUnsigned
- * @dataProvider provideToUnsigned
- */
- public function testToUnsigned( $expected, $input ) {
- $result = IP::toUnsigned( $input );
- $this->assertTrue( $result === false || is_string( $result ) || is_int( $result ) );
- $this->assertEquals( $expected, $result );
- }
-
- /**
- * Provider for IP::testToUnsigned()
- */
- public static function provideToUnsigned() {
- return array(
- array( 1, '0.0.0.1' ),
- array( 16909060, '1.2.3.4' ),
- array( 2130706433, '127.0.0.1' ),
- array( '2147483648', '128.0.0.0' ),
- array( 2130706440, '127.0.0.08' ),
- array( 2130706441, '127.0.0.09' ),
- array( '3735931646', '222.173.202.254' ),
- array( pow( 2, 32 ) - 1, '255.255.255.255' ),
- array( false, 'IN.VA.LI.D' ),
- array( 1, '::1' ),
- array( '42540766452641154071740215577757643572', '2001:0db8:85a3:0000:0000:8a2e:0370:7334' ),
- array( '42540766452641154071740215577757643572', '2001:db8:85a3::8a2e:0370:7334' ),
- array( false, 'IN:VA::LI:D' ),
- array( false, ':::1' )
- );
- }
-
/**
* @covers IP::toHex
* @dataProvider provideToHex