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) isnotNone# 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."""ifnot isinstance(text, str) or text.count("/") != 1:
returnNone
address, digits = text.split("/")
if len(digits) < 1or len(digits) > 3:
returnNonefor ch in digits:
ifnot ("0" <= ch <= "9"):
returnNoneif len(digits) > 1and digits[0] == "0":
returnNone
prefix = int(digits)
v4 = ipv4_value(address)
if v4 isnotNone:
return CidrBlock(4, [v4], prefix) if prefix <= 32elseNone
v6 = ipv6_groups(address)
if v6 isnotNone:
return CidrBlock(6, v6, prefix) if prefix <= 128elseNonereturnNone