Functional Weave
Code in TypeScript

net.cidr@1.0.0

impl/python/is_cidr.py

1,224 bytes · the Python implementation · view raw

from typing import List, NamedTuple, Optional

from .net_ipv4_parse_ipv4 import ipv4_value
from .net_ipv6_parse_ipv6 import ipv6_groups


def is_cidr(text: str) -> bool:
    """True for a well-formed IPv4 (prefix 0-32) or IPv6 (prefix 0-128) block; never raises."""
    return cidr_block(text) is not None


# Exported for the other functions of this group; not part of its contract.


class CidrBlock(NamedTuple):
    version: int
    bits: List[int]
    prefix: int


def cidr_block(text: object) -> Optional[CidrBlock]:
    """The block, or None when the text is not address/prefix with a strict decimal prefix."""
    if not isinstance(text, str) or text.count("/") != 1:
        return None
    address, digits = text.split("/")
    if len(digits) < 1 or len(digits) > 3:
        return None
    for ch in digits:
        if not ("0" <= ch <= "9"):
            return None
    if len(digits) > 1 and digits[0] == "0":
        return None
    prefix = int(digits)
    v4 = ipv4_value(address)
    if v4 is not None:
        return CidrBlock(4, [v4], prefix) if prefix <= 32 else None
    v6 = ipv6_groups(address)
    if v6 is not None:
        return CidrBlock(6, v6, prefix) if prefix <= 128 else None
    return None