Functional Weave
Code in Rust

net.ipv6@1.0.0

impl/python/format_ipv6.py

1,435 bytes · the Python implementation · view raw

from typing import Sequence

from .net_ipv4_format_ipv4 import format_ipv4


def format_ipv6(groups: Sequence[int]) -> str:
    """RFC 5952 canonical text for eight 16-bit groups.

    Lower-case hex, no leading zeros, the longest run of two or more zero
    groups written "::" (the first on a tie, never a single group). An
    IPv4-mapped address (::ffff:0:0/96) keeps its dotted-quad tail.
    """
    if isinstance(groups, (str, bytes)) or not isinstance(groups, (list, tuple)) or len(groups) != 8:
        raise ValueError("IPv6 groups must be eight integers from 0 to 65535")
    for g in groups:
        if isinstance(g, bool) or not isinstance(g, int) or g < 0 or g > 65535:
            raise ValueError("IPv6 groups must be eight integers from 0 to 65535")
    if list(groups[:6]) == [0, 0, 0, 0, 0, 0xFFFF]:
        return "::ffff:" + format_ipv4(groups[6] * 65536 + groups[7])
    best_start, best_length = -1, 0
    i = 0
    while i < 8:
        if groups[i] != 0:
            i += 1
            continue
        j = i
        while j < 8 and groups[j] == 0:
            j += 1
        # Strictly longer, so the first of two equal runs wins.
        if j - i > best_length:
            best_start, best_length = i, j - i
        i = j
    hexes = ["%x" % g for g in groups]
    if best_length < 2:
        return ":".join(hexes)
    return ":".join(hexes[:best_start]) + "::" + ":".join(hexes[best_start + best_length:])