PHP Conversion between and IP Address and an integer

I’ve been spending quite a bit of time on a program recently, and have taken for granted these two functions that I wrote for it a while ago. The convert back and forth between an IP address and the integer representation of the IP address.

For example, the IP address ‘207.210.219.125’ can also be represented as ‘3486702461’. The magic behind the calculation involves converting each octet of the IP address into binary, and then reading the entire 32 bits as a single unsigned integer.

The PHP code uses some bitwise functions to do this pretty easily (Although it took some experimenting to get it right). I’ve named the functions the same as their MySQL equivelents. inet_ntoa = number to address and int_aton = address to number. That’s right MySQL supports them directly. It’s much better for MySQL to work with the integers rather than the string representations.

function inet_aton($ip_address)
{
    if(! preg_match("/[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+$/",$ip_address)) {
        return;
    }
    list($octet1, $octet2, $octet3, $octet4) = split('\.',$ip_address);

    $ipaddress_number = (double)
        (($octet1 & 255) << 24 ) |
        (($octet2 & 255) << 16 ) |
        (($octet3 & 255) << 8 ) |
        ($octet4 & 255 ) ;
    ## PHP doesn't support unsigned ints, so we "fake" it into returning a double
    $return_number = doubleval(sprintf("%u", $ipaddress_number));
    return $return_number;
}


function inet_ntoa($ip_number)
{
    if(! is_numeric($ip_number)) {
        return $ip_number;
    }
    ## PHP doesn't support unsigned int's, so we'll use a double
    $ip_number = doubleval($ip_number);
    $octet1 = $ip_number >> 24 & 255;
    $octet2 = $ip_number >> 16 & 255;
    $octet3 = $ip_number >> 8 & 255;
    $octet4 = $ip_number & 255;
    $ip_address = $octet1 .'.'. $octet2 .'.'. $octet3 .'.'. $octet4 ;
    return $ip_address;
}

One thought on “PHP Conversion between and IP Address and an integer”

Leave a Reply

Your email address will not be published. Required fields are marked *