IPv6 address formatting

Expands or shortens IPv6 addresses in short or extended notation.

There’s no place like ::1. Not even 127.0.0.1.

IPv6-Adressen sind deutlich länger als IPv4-Adressen und lassen sich im Gegensatz zu letzteren auf mehrere Weisen darstellen. Zum Speichern oder Verarbeiten von solchen Adressen ist es aber praktisch erforderlich, sie in eine einheitliche Form zu bringen, da unterschiedliche Zeichenketten von IPv6-Adressen eben nicht unbedingt auch eine andere Adresse bedeuten.

Diese beiden Funktionen bringen eine IPv6-Adresse (z. B. 1:2:345:0:0:0:06fa:abc) jeweils in die vollständige Form fester Länge (0001:0002:0345:0000:0000:0000:06fa:0abc) bzw. in die kürzestmögliche Form (1:2:345::6fa:abc). Dabei wird die angegebene Adresse auch auf Gültigkeit geprüft.

Compatibility: PHP Version 5.0 or newer

Download

ipv6-format.inc.php2.8 KiBQuelltext der IPv6-Funktionen

Contents of the file ipv6-format.inc.php:

<?php
// Expands an IPv6 address into its unshortened form.
//
// ip_addr = (string) IPv6 address to expand.
//
// Returns (string) Unshortened IPv6 address, or {{false}} for invalid input.
//
function ExpandIPv6($ip_addr)
{
    $ip_addr = strtolower($ip_addr);

    // First check for valid characters
    // Zuerst auf gültige Zeichen prüfen
    if (!preg_match('/^[0-9a-f:]+$/', $ip_addr))
        return false;

    // "::" is only allowed once
    // "::" darf nur einmal vorkommen
    if (substr_count($ip_addr, '::') > 1)
        return false;

    // Resolve "::"
    // "::" auflösen
    if ($ip_addr == '::')
        $ip_addr = '0:0:0:0:0:0:0:0';
    $ip_addr = preg_replace('_^::_', '*:', $ip_addr);
    $ip_addr = preg_replace('_::$_', ':*', $ip_addr);
    $ip_addr = str_replace('::', ':*:', $ip_addr);
    $cnt = count(explode(':', $ip_addr));
    if ($cnt <= 8)
    {
        if (strpos($ip_addr, ':*') !== false)
            $ip_addr = str_replace(':*', str_repeat(':0', 8 - ($cnt - 1)), $ip_addr);
        else if (strpos($ip_addr, '*:') !== false)
            $ip_addr = str_replace('*:', str_repeat('0:', 8 - ($cnt - 1)), $ip_addr);
    }

    // Split and check chunks
    // Blöcke zerlegen und prüfen
    $expanded = '';
    $chunks = explode(':', $ip_addr);
    if (count($chunks) != 8)
        return false;
    foreach ($chunks as $chunk)
    {
        if (!preg_match('/^[0-9a-f]{1,4}$/', $chunk))
            return false;
        $expanded .= (strlen($expanded) > 0 ? ':' : '') . str_pad($chunk, 4, '0', STR_PAD_LEFT);
    }
    return $expanded;
}

// Shortens an IPv6 address into its shortest-possible form.
//
// ip_addr = (string) IPv6 address to shorten.
//
// Returns (string) Shortened IPv6 address, or {{false}} for invalid input.
//
function ShortenIPv6($ip_addr)
{
    // Normalise and check address
    // Adresse normalisieren und prüfen
    $ip_addr = ExpandIPv6($ip_addr);
    if ($ip_addr === false)
        return false;
   
    // Remove leading zeroes
    // Führende Nullen entfernen
    $ip_addr = preg_replace('_(?<=^|:)0+(?=[0-9a-f]+(:|$))_', '', $ip_addr);
   
    // Find largest zero chunk and replace it with "::" once
    // Längsten Null-Teil einmal mit "::" ersetzen
    $ip_addr = preg_replace('_^0:0:0:0:0:0:0:0$_', '::', $ip_addr, 1);
    if (strpos($ip_addr, '::') === false)
        $ip_addr = preg_replace('_(^|:)0:0:0:0:0:0:0(:|$)_', '::', $ip_addr, 1);
    if (strpos($ip_addr, '::') === false)
        $ip_addr = preg_replace('_(^|:)0:0:0:0:0:0(:|$)_', '::', $ip_addr, 1);
    if (strpos($ip_addr, '::') === false)
        $ip_addr = preg_replace('_(^|:)0:0:0:0:0(:|$)_', '::', $ip_addr, 1);
    if (strpos($ip_addr, '::') === false)
        $ip_addr = preg_replace('_(^|:)0:0:0:0(:|$)_', '::', $ip_addr, 1);
    if (strpos($ip_addr, '::') === false)
        $ip_addr = preg_replace('_(^|:)0:0:0(:|$)_', '::', $ip_addr, 1);
    if (strpos($ip_addr, '::') === false)
        $ip_addr = preg_replace('_(^|:)0:0(:|$)_', '::', $ip_addr, 1);
    if (strpos($ip_addr, '::') === false)
        $ip_addr = preg_replace('_(^|:)0(:|$)_', '::', $ip_addr, 1);
    return $ip_addr;
}
?>

Licence and terms of use

This software is freely available as source code and compiled version, without restrictions (“public domain”). There is no warranty, not even for merchantability or fitness for a particular purpose. I am not liable for any damage caused through appropriate or inappropriate use.

Statistic data

  • Created on 2012-03-04.