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.
- Do I violate the standard in any way?
- Can I do anything more efficiently?
As you can probably tell, I am not concerned with validating the addresses.