Skip to content

Instantly share code, notes, and snippets.

@lt
Forked from nikic/gist:4162505
Created November 28, 2012 17:07
Show Gist options
  • Save lt/4162568 to your computer and use it in GitHub Desktop.
Save lt/4162568 to your computer and use it in GitHub Desktop.
Regex to validate (IPv4) CIDR notation (with capture)
Repeating patterns, matches 0-255 in each octet, followed by /0-32
\b(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)/(3[0-2]|[1-2]?[0-9])\b
Using subpatterns to achieve the same thing.
\b(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(?1)\.(?1)\.(?1)/(3[0-2]|[1-2]?[0-9])\b
@lt
Copy link
Author

lt commented May 16, 2016

function matchCIDR(string $cidr, string $ip)
{
    if (!preg_match('~^((?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(?2)\.(?2)\.(?2))/(3[0-2]|[1-2]?[0-9])$~', $cidr, $matches)) {
        throw new \InvalidArgumentException('Invalid IPv4 CIDR notation');
    }

    if (!preg_match('~^(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(?1)\.(?1)\.(?1)$~', $ip)) {
        throw new \InvalidArgumentException('Invalid IPv4 address');
    }

    return ((ip2long($matches[1]) ^ ip2long($ip)) >> (32 - (int)$matches[2])) === 0;
}

var_dump(
    matchCIDR('127.0.0.0/24', '127.0.0.255'),
    matchCIDR('127.0.0.0/24', '127.0.1.0'),
    matchCIDR('127.0.0.1/32', '255.255.255.255'),
    matchCIDR('127.0.0.1/0', '255.255.255.255')
);

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment