In various situation, it is important to check if a given IP address is within a predefined subnet. For example if we would like to allow access from only a specific range of IP addresses we would create a "white list" of those addresses. Similarly if we would like to deny access based on a set of rules regarding the IP address of the visitor.

Fixed list of IP add resses

To create a "white-list" we could simply list all the IP addresses that we allow and then look up if the given IP address is in this list. For example:

use 5.010; my $ip = '1.2.3.4'; my @white_list = ('1.2.3.4', '3.71.5.42', '21.22.23.24'); if (grep { $ip eq $_ } @white_list) { say 'Allow access'; } else { say 'Deny access'; }

Of course if the @white_list has a lot of elements, every look-up will be time consuming.

We could improve it using the any function of List::MoreUtils which similar to the all function, short-circuits.

use 5.010; use List::MoreUtils qw(any); my $ip = '1.2.3.4'; my @white_list = ('1.2.3.4', '3.71.5.42', '21.22.23.24'); if (any { $ip eq $_ } @white_list) { say 'Allow access'; } else { say 'Deny access'; }

Alternatively, and gaining even more peformance boost, we could build a look-up hash:

use 5.010; my %white_list = map { $_ => 1 } ('1.2.3.4', '3.71.5.42', '21.22.23.24'); if ($white_list{$ip}) { say 'Allow access'; } else { say 'Deny access'; }

That's possible, but if we would like to allow (or disallow) all the IP addresses in a given class-A subnet, listing all of them will use-up quite some memory.

Using Net::Subnet