Jim said:
Is there a module, or a readily available algorithm, for calculating
the next available IP Address?
Let's say I have an array
('10.1.1.1','10.1.1.2','10.1.1.3','10.1.1.10'). I want to find that
the next available address is 10.1.1.4. Thanks.
Hi Jim,
there may be such a module. I suggest you search CPAN for 'IP'.
Regardless, this is simple enough a task that a simple-minded approach
should do fine: (Sue me.)
use strict;
use warnings;
sub increment_ip ($) {
my $ip = shift;
my $i = 3;
while ($i >= 0) {
$ip->[$i]++;
if ($ip->[$i] > 255) {
$ip->[$i] = 0;
$i--;
}
else {
last;
}
}
return $ip;
}
sub decrement_ip ($) {
my $ip = shift;
my $i = 3;
while ($i >= 0) {
$ip->[$i]--;
if ($ip->[$i] < 0) {
$ip->[$i] = 255;
$i--;
}
else {
last;
}
}
return $ip;
}
sub compare_ips ($$) {
my $ip1 = shift;
my $ip2 = shift;
my $i = 0;
while ($i < 4) {
return -1 if $ip1->[$i] < $ip2->[$i];
return 1 if $ip1->[$i] > $ip2->[$i];
$i++;
}
return 0;
}
sub ip_iterator ($;\@) {
my $start = shift;
my $ary = shift || [];
$start = [map {0+$_} split /\./, $start];
@$ary = sort {
$a->[0] <=> $b->[0] ||
$a->[1] <=> $b->[1] ||
$a->[2] <=> $b->[2] ||
$a->[3] <=> $b->[3]
} map {
[map 0+$_, split /\./, $_]
} @$ary;
{
my $i = 0;
while (compare_ips($start, $ary->[$i]) == -1) {
shift @$ary;
$i++;
}
}
$start = decrement_ip $start;
return sub {
$start = increment_ip $start;
while (@$ary and not compare_ips $ary->[0], $start) {
$start = increment_ip $start;
shift @$ary;
}
return join '.', @$start;
};
}
# Here comes the code you need to care about:
my @ary = qw(10.1.1.1 10.1.1.2 10.1.1.3 10.1.1.10);
my $start = '10.1.1.1';
my $iter = ip_iterator $start, @ary;
foreach (1..20) {
print $iter->(), "\n";
}
The implementation should be fairly efficient once the iterator has been
generated as a closure.
Now, if I were to make this a module that lets you deal with those IP
array-refs themselves, I'd make them objects and possibly overload the
+, -, and <=> operators to look nicer than "increment_ip" and friends.
The code hasn't been thoroughly tested. (What about start values of
'0.0.0.0' or '255.255.255.255'? What about invalid input?)
If you want me to read any answers you post to comp.lang.perl.misc,
you'll need to send me a cc. I read this on comp.lang.perl.modules.
Steffen