ip-to-regexp.pl 2.3 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495
  1. use Modern::Perl;
  2. use Net::Whois::Parser qw/parse_whois/;
  3. sub main {
  4. my $ip = shift(@ARGV);
  5. die "Provide an IP number as argument.\n" unless $ip;
  6. print get_regexp_ip(get_range($ip)), "\n";
  7. }
  8. sub get_range {
  9. my $ip = shift;
  10. my $response = parse_whois(domain => $ip);
  11. my $re = '(?:[0-9]{1,3}\.){3}[0-9]{1,3}';
  12. my ($start, $end) = $response->{inetnum} =~ /($re) *- *($re)/;
  13. return $start, $end;
  14. }
  15. sub get_groups {
  16. my ($from, $to) = @_;
  17. my @groups;
  18. if ($from < 10) {
  19. my $to = $to >= 10 ? 9 : $to;
  20. push(@groups, [$from, $to]);
  21. $from = $to + 1;
  22. }
  23. while ($from < $to) {
  24. my $to = int($from/100) < int($to/100) ? $from + 99 - $from % 100 : $to;
  25. if ($from % 10) {
  26. push(@groups, [$from, $from + 9 - $from % 10]);
  27. $from += 10 - $from % 10;
  28. }
  29. if (int($from/10) < int($to/10)) {
  30. if ($to % 10 == 9) {
  31. push(@groups, [$from, $to]);
  32. $from = 1 + $to;
  33. } else {
  34. push(@groups, [$from, $to - 1 - $to % 10]);
  35. $from = $to - $to % 10;
  36. }
  37. } else {
  38. push(@groups, [$from - $from % 10, $to]);
  39. last;
  40. }
  41. if ($to % 10 != 9) {
  42. push(@groups, [$from, $to]);
  43. $from = 1 + $to; # jump from 99 to 100
  44. }
  45. }
  46. return \@groups;
  47. }
  48. sub get_regexp_range {
  49. my @chars;
  50. for my $group (@{get_groups(@_)}) {
  51. my ($from, $to) = @$group;
  52. my $char;
  53. for (my $i = length($from); $i >= 1; $i--) {
  54. if (substr($from, - $i, 1) eq substr($to, - $i, 1)) {
  55. $char .= substr($from, - $i, 1);
  56. } else {
  57. $char .= '[' . substr($from, - $i, 1) . '-' . substr($to, - $i, 1). ']';
  58. }
  59. }
  60. push(@chars, $char);
  61. }
  62. return join('|', @chars);
  63. }
  64. sub get_regexp_ip {
  65. my ($from, $to) = @_;
  66. my @start = split(/\./, $from);
  67. my @end = split(/\./, $to);
  68. my $regexp = "^";
  69. for my $i (0 .. 3) {
  70. if ($start[$i] eq $end[$i]) {
  71. $regexp .= $start[$i];
  72. } elsif ($start[$i] eq '0' and $end[$i] eq '255') {
  73. last;
  74. } elsif ($start[$i + 1] > 0) {
  75. $regexp .= '(' . $start[$i] . '\.('
  76. . get_regexp_range($start[$i + 1], '255') . ')|'
  77. . get_regexp_range($start[$i] + 1, $end[$i + 1]) . ')';
  78. $regexp .= '\.';
  79. last;
  80. } else {
  81. $regexp .= '(' . get_regexp_range($start[$i], $end[$i]) . ')$';
  82. last;
  83. }
  84. $regexp .= '\.' if $i < 3;
  85. }
  86. return $regexp;
  87. }
  88. main();