Skip to main content
replaced http://tools.ietf.org/html/rfc with https://www.rfc-editor.org/rfc/rfc
Source Link

I wrote the following function in PHP to represent IPv6 addresses as short as possible:

function ipv6_compress($ip){
    // Shorten first group of zeros
    if(substr($ip, 0, 4) == 0000) $ip = substr_replace($ip, '0', 0, 4);
    // Shorten full groups of zeros
    $ip = str_replace('0000:', '0:', $ip);
    // Remove leading zeros
    $ip = preg_replace('/:0{1,3}(?=\w)/', ':', $ip);
    // Remove longest extra group of zeros per [RFC 5952](httphttps://toolswww.ietfrfc-editor.org/htmlrfc/rfc5952)
    if(strpos('::') !== false) return $ip; // But don't if a :: is already present as entered
    $pos = strpos($ip, '0:0:0:0:0:0:0:');
    if($pos !== false) return $ip = substr_replace($ip, '::', $pos, 14);
    $pos = strpos($ip, '0:0:0:0:0:0:');
    if($pos !== false) return $ip = substr_replace($ip, '::', $pos, 12);
    $pos = strpos($ip, '0:0:0:0:0:');
    if($pos !== false) return $ip = substr_replace($ip, '::', $pos, 10);
    $pos = strpos($ip, '0:0:0:0:');
    if($pos !== false) return $ip = substr_replace($ip, '::', $pos, 8);
    $pos = strpos($ip, '0:0:0:');
    if($pos !== false) return substr_replace($ip, '::', $pos, 6);
    $pos = strpos($ip, '0:0:');
    if($pos !== false) return substr_replace($ip, '::', $pos, 4);
    return $ip;
}

I attempt to adhere to RFC 5952RFC 5952.

  1. Do I violate the standard in any way?
  2. Can I do anything more efficiently?

As you can probably tell, I am not concerned with validating the addresses.

I wrote the following function in PHP to represent IPv6 addresses as short as possible:

function ipv6_compress($ip){
    // Shorten first group of zeros
    if(substr($ip, 0, 4) == 0000) $ip = substr_replace($ip, '0', 0, 4);
    // Shorten full groups of zeros
    $ip = str_replace('0000:', '0:', $ip);
    // Remove leading zeros
    $ip = preg_replace('/:0{1,3}(?=\w)/', ':', $ip);
    // Remove longest extra group of zeros per [RFC 5952](http://tools.ietf.org/html/rfc5952)
    if(strpos('::') !== false) return $ip; // But don't if a :: is already present as entered
    $pos = strpos($ip, '0:0:0:0:0:0:0:');
    if($pos !== false) return $ip = substr_replace($ip, '::', $pos, 14);
    $pos = strpos($ip, '0:0:0:0:0:0:');
    if($pos !== false) return $ip = substr_replace($ip, '::', $pos, 12);
    $pos = strpos($ip, '0:0:0:0:0:');
    if($pos !== false) return $ip = substr_replace($ip, '::', $pos, 10);
    $pos = strpos($ip, '0:0:0:0:');
    if($pos !== false) return $ip = substr_replace($ip, '::', $pos, 8);
    $pos = strpos($ip, '0:0:0:');
    if($pos !== false) return substr_replace($ip, '::', $pos, 6);
    $pos = strpos($ip, '0:0:');
    if($pos !== false) return substr_replace($ip, '::', $pos, 4);
    return $ip;
}

I attempt to adhere to RFC 5952.

  1. Do I violate the standard in any way?
  2. Can I do anything more efficiently?

As you can probably tell, I am not concerned with validating the addresses.

I wrote the following function in PHP to represent IPv6 addresses as short as possible:

function ipv6_compress($ip){
    // Shorten first group of zeros
    if(substr($ip, 0, 4) == 0000) $ip = substr_replace($ip, '0', 0, 4);
    // Shorten full groups of zeros
    $ip = str_replace('0000:', '0:', $ip);
    // Remove leading zeros
    $ip = preg_replace('/:0{1,3}(?=\w)/', ':', $ip);
    // Remove longest extra group of zeros per [RFC 5952](https://www.rfc-editor.org/rfc/rfc5952)
    if(strpos('::') !== false) return $ip; // But don't if a :: is already present as entered
    $pos = strpos($ip, '0:0:0:0:0:0:0:');
    if($pos !== false) return $ip = substr_replace($ip, '::', $pos, 14);
    $pos = strpos($ip, '0:0:0:0:0:0:');
    if($pos !== false) return $ip = substr_replace($ip, '::', $pos, 12);
    $pos = strpos($ip, '0:0:0:0:0:');
    if($pos !== false) return $ip = substr_replace($ip, '::', $pos, 10);
    $pos = strpos($ip, '0:0:0:0:');
    if($pos !== false) return $ip = substr_replace($ip, '::', $pos, 8);
    $pos = strpos($ip, '0:0:0:');
    if($pos !== false) return substr_replace($ip, '::', $pos, 6);
    $pos = strpos($ip, '0:0:');
    if($pos !== false) return substr_replace($ip, '::', $pos, 4);
    return $ip;
}

I attempt to adhere to RFC 5952.

  1. Do I violate the standard in any way?
  2. Can I do anything more efficiently?

As you can probably tell, I am not concerned with validating the addresses.

Rollback to Revision 6
Source Link
200_success
  • 144.2k
  • 22
  • 188
  • 473

##EDIT:

Per this answer:

function ipv6_compress($ip){
    // Shorten first group of zeros
    if(substr($ip, 0, 4) === '0000') $ip = substr_replace($ip, ':0', 0, 4);
    // Shorten full groups of zeros
    $ip = str_replace(':0000', ':0', $ip);
    // Remove leading zeros
    $ip = preg_replace('/:0{1,3}(?=\w)/', ':', $ip); //return $ip;
    // Remove longest extra group of zeros per [RFC 5952](http://tools.ietf.org/html/rfc5952)
    $z = ':0:0:0:0:0:0:0:'; // Set chain
    while(strpos($ip, '::') === false && strlen($z) >= 5){ // While no :: and chain still possible
        $pos = strpos($ip, $z);
        if($pos !== false){ return substr_replace($ip, '::', $pos, strlen($z)); break; } // Replace chain and return
        $z = substr($z, 0, strlen($z) - 2); // cut away one '0:' to shorten the chain
    }
    return $ip; // return
}

##EDIT:

Per this answer:

function ipv6_compress($ip){
    // Shorten first group of zeros
    if(substr($ip, 0, 4) === '0000') $ip = substr_replace($ip, ':0', 0, 4);
    // Shorten full groups of zeros
    $ip = str_replace(':0000', ':0', $ip);
    // Remove leading zeros
    $ip = preg_replace('/:0{1,3}(?=\w)/', ':', $ip); //return $ip;
    // Remove longest extra group of zeros per [RFC 5952](http://tools.ietf.org/html/rfc5952)
    $z = ':0:0:0:0:0:0:0:'; // Set chain
    while(strpos($ip, '::') === false && strlen($z) >= 5){ // While no :: and chain still possible
        $pos = strpos($ip, $z);
        if($pos !== false){ return substr_replace($ip, '::', $pos, strlen($z)); break; } // Replace chain and return
        $z = substr($z, 0, strlen($z) - 2); // cut away one '0:' to shorten the chain
    }
    return $ip; // return
}
added 936 characters in body
Source Link
Mooseman
  • 199
  • 3
  • 12

##EDIT:

Per this answer:

function ipv6_compress($ip){
    // Shorten first group of zeros
    if(substr($ip, 0, 4) === '0000') $ip = substr_replace($ip, ':0', 0, 4);
    // Shorten full groups of zeros
    $ip = str_replace(':0000', ':0', $ip);
    // Remove leading zeros
    $ip = preg_replace('/:0{1,3}(?=\w)/', ':', $ip); //return $ip;
    // Remove longest extra group of zeros per [RFC 5952](http://tools.ietf.org/html/rfc5952)
    $z = ':0:0:0:0:0:0:0:'; // Set chain
    while(strpos($ip, '::') === false && strlen($z) >= 5){ // While no :: and chain still possible
        $pos = strpos($ip, $z);
        if($pos !== false){ return substr_replace($ip, '::', $pos, strlen($z)); break; } // Replace chain and return
        $z = substr($z, 0, strlen($z) - 2); // cut away one '0:' to shorten the chain
    }
    return $ip; // return
}

##EDIT:

Per this answer:

function ipv6_compress($ip){
    // Shorten first group of zeros
    if(substr($ip, 0, 4) === '0000') $ip = substr_replace($ip, ':0', 0, 4);
    // Shorten full groups of zeros
    $ip = str_replace(':0000', ':0', $ip);
    // Remove leading zeros
    $ip = preg_replace('/:0{1,3}(?=\w)/', ':', $ip); //return $ip;
    // Remove longest extra group of zeros per [RFC 5952](http://tools.ietf.org/html/rfc5952)
    $z = ':0:0:0:0:0:0:0:'; // Set chain
    while(strpos($ip, '::') === false && strlen($z) >= 5){ // While no :: and chain still possible
        $pos = strpos($ip, $z);
        if($pos !== false){ return substr_replace($ip, '::', $pos, strlen($z)); break; } // Replace chain and return
        $z = substr($z, 0, strlen($z) - 2); // cut away one '0:' to shorten the chain
    }
    return $ip; // return
}
Tweeted twitter.com/#!/StackCodeReview/status/597842865209892864
edited tags
Link
Jamal
  • 34.9k
  • 13
  • 133
  • 237
Loading
edited title
Link
Mooseman
  • 199
  • 3
  • 12
Loading
edited tags
Link
200_success
  • 144.2k
  • 22
  • 188
  • 473
Loading
edited tags
Link
user34073
user34073
Loading
edited tags
Link
rolfl
  • 97.5k
  • 17
  • 218
  • 418
Loading
Source Link
Mooseman
  • 199
  • 3
  • 12
Loading