use v5.36; use JSON::MaybeXS; use Path::Tiny; use Socket "inet_aton"; my @ranges; for (path($ARGV[0])->lines) { my $range= decode_json($_); if ($range->{start_ip} =~ /^\d+\./) { $range->{min}= inet_aton($range->{start_ip}); $range->{max}= inet_aton($range->{end_ip}); push @ranges, $range; } } @ranges= sort { $a->{min} cmp $b->{min} } @ranges; sub find_ip($ip) { my $ip_str= inet_aton($ip); my ($min, $max)= (0, $#ranges); while ($min <= $max) { my $mid= int(($min+$max)/2); if ($ranges[$mid]{min} gt $ip_str) { $max= $mid-1; } elsif ($ranges[$mid]{max} lt $ip_str) { $min= $mid+1; } else { return $ranges[$mid]; } } return undef; } use Data::Printer; say "Enter IPv4"; say "Type ^D to terminate"; while (<STDIN>) { chomp; &p( find_ip($_) ); }
Examples:
$ perl test.pl country_asn.json Enter IPv4 Type ^D to terminate 1.1.1.1 { as_domain "cloudflare.com", as_name "Cloudflare, Inc.", asn "AS13335", continent "OC", continent_name "Oceania", country "AU", country_name "Australia", end_ip "1.1.1.255" (dualvar: 1.1), max "�", min "\0", start_ip "1.1.1.0" (dualvar: 1.1) } 8.8.4.4 { as_domain "google.com", as_name "Google LLC", asn "AS15169", continent "NA", continent_name "North America", country "US", country_name "United States", end_ip "8.8.4.255" (dualvar: 8.8), max "\b\b�", min "\b\b\0", start_ip "8.8.4.0" (dualvar: 8.8) }
Parsing that blob of json is fairly slow, so you probably want this to stay loaded in memory.
I don't have any good ideas offhand for how to query this out of a database... maybe someone else has ideas. I bet Postgres has some special index type that handles ranges of values.
If you loaded this into a database, I think you'd get decent performance from
That should follow the index straight to the record you want, then stop iterating as soon as it finds it.CREATE TABLE ip_ranges ( ... ipmin varbinary(4), ipmax varbinary(4), ... ); CREATE INDEX ON ip_ranges (ipmax ASC); SELECT * FROM ip_ranges WHERE ipmax >= ? and ipmin <= ? ORDER BY ipmax LIMIT 1
In reply to Re: IP Lookup Tables
by NERDVANA
in thread IP Lookup Tables
by monsignor
For: | Use: | ||
& | & | ||
< | < | ||
> | > | ||
[ | [ | ||
] | ] |