Lies and lies within
Weekly challenge 363 — 2 March 2026
Week 363: 2 Mar 2026
You are given an IPv4 address and an IPv4 network (in CIDR format). Write a script to determine whether both are valid and the address falls within the network.
For more information see this Wikipedia article.
Example 1 Input: $ip_addr = '192.168.1.45' $domain = '192.168.1.0/24' Output: true Example 2 Input: $ip_addr = '10.0.0.256' $domain = '10.0.0.0/24' Output: false Example 3 Input: $ip_addr = '172.16.8.9' $domain = '172.16.8.9/32' Output: true Example 4 Input: $ip_addr = '172.16.4.5' $domain = '172.16.0.0/14' Output: true Example 5 Input: $ip_addr = '192.0.2.0' $domain = '192.0.2.0/25' Output: true
Confession: I submitted this challenge which arose from a need to filter IP addresses with permission to access a website.
An IPv4 address (ip) is a 32-bit integer. The usual dotted representation comprises the 32 bits divided into 4 octets, with each of these represented as the decimal equivalent (a.b.c.d):
ip = a × 224 + b × 216 + c × 28 + d
There are three steps to this challenge:
Step 1 is to check the validity of the supplied IPv4 address. A valid address comprises 4 integers in the range 0-255 separated by dots (.) and one line of code suffices to check that.
Step 2 is to validate the supplied network (or domain). It must be a valid address (as above) followed by a slash (/) and an integer (n) in the range 0-32.
To validate the domain, a mask (m) can be created which comprises n one bits followed by (32 - n) zero bits.
A valid domain (d) is then one where d ∧ m = d, that is,
where the low order 32 - n bits of the domain are all zero.
The domain address is the lowest numbered address within the domain,
and the domain contains 2(32 - n) addresses.
Step 3 is to check that the address falls within the domain
which it does if ip ∧ m = d.
Fortunately, Perl supports all the operators needed to perform the needed bitwise operations.
#!/usr/bin/perl # Blog: http://ccgi.campbellsmiths.force9.co.uk/challenge use v5.26; # The Weekly Challenge - 2026-03-02 use utf8; # Week 363 - task 2 - Subnet sheriff use warnings; # Peter Campbell Smith binmode STDOUT, ':utf8'; use Encode; # test limits of subnet my $subnet = '192.168.1.0/24'; subnet_sheriff('192.168.1.45', $subnet); # typical subnet_sheriff('192.168.1.0', $subnet); # first subnet_sheriff('192.168.1.255', $subnet); # last subnet_sheriff('192.168.2.0', $subnet); # outside subnet_sheriff('1.1.1.1', '1.1.255.1/24'); # invalid # examples from challenge subnet_sheriff('192.168.1.45', '192.168.1.0/24'); # true subnet_sheriff('10.0.0.256', '10.0.0.0/24'); # invalid subnet_sheriff('172.16.4.5', '172.16.0.0/14'); # true subnet_sheriff('192.0.2.0', '192.0.2.0/25'); # true # smallest and largest subnets subnet_sheriff('1.2.3.4', '1.2.3.4/32'); # true subnet_sheriff('1.2.3.4', '0.0.0.0/0'); # true sub subnet_sheriff { my ($address, $domain, $good, $domain2, $mask, $within, $address2); # initialise ($address, $domain) = @_; say qq[\nInput: \$address = '$address', \$domain = '$domain']; # validate address unless ($address =~ m|([0-9]{1,3})\.([0-9]{1,3})\.([0-9]{1,3})\.([0-9]{1,3})| and $1 <= 255 and $2 <= 255 and $3 <= 255 and $4 <= 255) { say qq[Output: false - invalid address]; return; } $address2 = ($1 * 2**24) + ($2 * 2**16) + ($3 * 2**8) + $4; # validate domain $good = $domain =~ m|([0-9]{1,3})\.([0-9]{1,3})\.([0-9]{1,3})\.([0-9]{1,3})/([0-9]{1,2})| ? 1 : 0; $good = ($good and $5 <= 32); if ($good) { $domain2 = $1 * (2 ** 24) + $2 * (2 ** 16) + $3 * (2 ** 8) + $4; $mask = (2 ** $5 - 1) << (32 - $5); $good = ($domain2 & $mask) == $domain2; } unless ($good) { say qq[Output: false - invalid subnet]; return; } # check that address falls within subnet $within = ($address2 & $mask) == $domain2 ? 'true' : 'false - address outside subnet'; say qq[Output: $within]; }
Input: $address = '192.168.1.45', $domain = '192.168.1.0/24' Output: true Input: $address = '192.168.1.0', $domain = '192.168.1.0/24' Output: true Input: $address = '192.168.1.255', $domain = '192.168.1.0/24' Output: true Input: $address = '192.168.2.0', $domain = '192.168.1.0/24' Output: false - address outside subnet Input: $address = '1.1.1.1', $domain = '1.1.255.1/24' Output: false - invalid subnet Input: $address = '192.168.1.45', $domain = '192.168.1.0/24' Output: true Input: $address = '10.0.0.256', $domain = '10.0.0.0/24' Output: false - invalid address Input: $address = '172.16.4.5', $domain = '172.16.0.0/14' Output: true Input: $address = '192.0.2.0', $domain = '192.0.2.0/25' Output: true Input: $address = '1.2.3.4', $domain = '1.2.3.4/32' Output: true Input: $address = '1.2.3.4', $domain = '0.0.0.0/0' Output: true
Any content of this website which has been created by Peter Campbell Smith is in the public domain