Canonicalize CIDR: Difference between revisions
Content added Content deleted
(→{{header|Perl}}: Add comments, remove some extraneous parens.) |
|||
Line 6: | Line 6: | ||
=={{header|Perl}}== |
=={{header|Perl}}== |
||
<lang perl> |
<lang perl>#!/usr/bin/env perl |
||
#!/usr/bin/env perl |
|||
use v5.16; |
use v5.16; |
||
use Socket qw(inet_aton inet_ntoa); |
use Socket qw(inet_aton inet_ntoa); |
||
Line 17: | Line 16: | ||
for (@ARGV) { |
for (@ARGV) { |
||
# dotted-decimal / bits in network part |
|||
my ($dotted, $size) = split m#/#; |
my ($dotted, $size) = split m#/#; |
||
⚫ | |||
# get IP as binary string |
|||
⚫ | |||
# Replace the host part with all zeroes |
|||
substr($binary,$size) = "0" x (32 - $size); |
substr($binary,$size) = "0" x (32 - $size); |
||
⚫ | |||
# Convert back to dotted-decimal |
|||
⚫ | |||
# And output |
|||
print "$dotted/$size\n"; |
print "$dotted/$size\n"; |
||
⚫ | |||
} |
|||
⚫ | |||
{{Out}} |
{{Out}} |
||
<pre>$ canonicalize_cidr.pl 87.70.141.1/22 |
<pre>$ canonicalize_cidr.pl 87.70.141.1/22 |
Revision as of 03:54, 9 July 2020
Canonicalize CIDR
You are encouraged to solve this task according to the task description, using any language you may know.
You are encouraged to solve this task according to the task description, using any language you may know.
Implement a function or program that, given a range of IP addresses in CIDR notation (dotted-decimal/network-bits), will return/output the same range in canonical form, that is, with none of the host bits set.
Example: given 87.70.141.1/22, your code should output 87.70.140.0/22.
Perl
<lang perl>#!/usr/bin/env perl use v5.16; use Socket qw(inet_aton inet_ntoa);
- canonicalize a CIDR block: make sure none of the host bits are set
if (!@ARGV) {
chomp(@ARGV = <>);
}
for (@ARGV) {
# dotted-decimal / bits in network part my ($dotted, $size) = split m#/#;
# get IP as binary string my $binary = sprintf "%032b", unpack('N', inet_aton $dotted);
# Replace the host part with all zeroes substr($binary,$size) = "0" x (32 - $size);
# Convert back to dotted-decimal $dotted = inet_ntoa(pack 'B32', $binary);
# And output print "$dotted/$size\n";
}</lang>
- Output:
$ canonicalize_cidr.pl 87.70.141.1/22 87.70.140.0/22
Python
<lang python>
- !/usr/bin/env python
- canonicalize a CIDR block specification:
- make sure none of the host bits are set
import sys from socket import inet_aton, inet_ntoa from struct import pack, unpack
for cidr in sys.argv[1:]:
# IP in dotted-decimal / bits in network part dotted, size_str = cidr.split('/') size = int(size_str)
numeric = unpack('!I', inet_aton(dotted))[0] # IP as an integer binary = f'{numeric:#034b}' # then as a padded binary string prefix = binary[:size + 2] # just the network part # (34 and +2 are to account # for leading '0b')
canon_binary = prefix + '0' * (32 - size) # replace host part with all zeroes canon_numeric = int(canon_binary, 2) # convert back to integer canon_dotted = inet_ntoa(pack('!I', (canon_numeric))) # and then to dotted-decimal print(f'{canon_dotted}/{size}') # output result
</lang>
- Output:
$ canonicalize_cidr.py 87.70.141.1/22 87.70.140.0/22