Skip to content

Instantly share code, notes, and snippets.

@smls

smls/01_whois.md Secret

Created December 19, 2015 12:11
Show Gist options
  • Save smls/9adf4b6707938445c050 to your computer and use it in GitHub Desktop.
Save smls/9adf4b6707938445c050 to your computer and use it in GitHub Desktop.
sub ip-to-number ($ip) {
do given $ip.split('.') {
.[0] +< 24 +
.[1] +< 16 +
.[2] +< 8 +
.[3] +< 0
}
}
class IntervalTree {
has $.min;
has $.max;
has $!center = ($!min + $!max) div 2;
has @!intervals;
has IntervalTree $!left;
has IntervalTree $!right;
method new ($min, $max) { self.bless(:$min, :$max) }
method insert (|c ($start, $end, $name)) {
if $end < $!center and $!min < $!center - 1 {
($!left //= self.new($!min, $!center)).insert(|c)
}
elsif $start > $!center and $!max > $!center {
($!right //= self.new($!center, $!max)).insert(|c)
}
else {
@!intervals.push: [$start, $end, $name, $end-$start]
}
}
method prepare {
@!intervals.=sort(*[3]);
$!left .prepare if $!left;
$!right.prepare if $!right;
}
method lookup ($n) {
my $best = ($n < $!center ?? ($!left .lookup($n) if $!left)
!! ($!right.lookup($n) if $!right));
$best ?? @!intervals.first({ return $best if .[3] > $best[3];
.[0] <= $n <= .[1] }) // $best
!! @!intervals.first({ .[0] <= $n <= .[1] })
}
}
sub MAIN ($ip-file, $query-file) {
my $index = IntervalTree.new(0, ip-to-number '255.255.255.255');
for $ip-file.IO.lines {
my ($start, $end, $name) = .split(' ', 3);
$index.insert(ip-to-number($start), ip-to-number($end), $name);
}
$index.prepare;
for $query-file.IO.lines -> $ip {
my $name = $index.lookup(ip-to-number $ip)[2];
say "$ip {$name // '<unknown>'}";
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment