The weekly challenge 363 - Task 2: Subnet Sheriff
1 #!/usr/bin/env perl
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63 use v5.36;
64
65 subnet_sheriff("192.168.1.45", "192.168.1.0/24");
66 subnet_sheriff("10.0.0.256", "10.0.0.0/24");
67 subnet_sheriff("172.16.8.9", "172.16.8.9/32");
68 subnet_sheriff("172.16.4.5", "172.16.0.0/14");
69 subnet_sheriff("192.0.2.0", "192.0.2.0/25");
70
71 sub subnet_sheriff($ip_addr, $domain) {
72 say "Input: $ip_addr, $domain";
73 return say "Output: false" unless $ip_addr =~ m/\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}/;
74 return say "Output: false" unless $domain =~ m/\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}\/\d{1,2}/;
75 return say "Output: false" unless ip_ok($ip_addr);
76 return say "Output: false" unless domain_ok($domain);
77 my @ip_binary = to_binary($ip_addr);
78 my ($ip_part, $mask) = split /\//, $domain;
79 my @domain_binary = to_binary($ip_part);
80 foreach my $digit (0..$mask-1) {
81 return say "Output: false" unless $ip_binary[$digit] == $domain_binary[$digit];
82 }
83 say "Output: true";
84 }
85
86 sub ip_ok($ip) {
87 my ($i,$j,$k,$l) = split /\./, $ip;
88 return 0 if $i > 255;
89 return 0 if $j > 255;
90 return 0 if $k > 255;
91 return 0 if $l > 255;
92 return 1;
93 }
94
95 sub domain_ok($domain) {
96 my ($ip, $mask) = split /\//, $domain;
97 return 0 if $mask > 32;
98 return 0 if $mask < 1;
99 return ip_ok($ip);
100 }
101
102 sub to_binary($ip) {
103 my @binary = ();
104 my ($i,$j,$k,$l) = split /\./, $ip;
105 foreach my $part (($i, $j, $k, $l)) {
106 foreach my $num ((128,64,32,16,8,4,2,1) ) {
107 if($part >= $num) {
108 push @binary, 1;
109 $part -= $num;
110 } else {
111 push @binary, 0;
112 }
113 }
114 }
115 return @binary;
116 }