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
![Task](http://static.miraheze.org/rosettacodewiki/thumb/b/ba/Rcode-button-task-crushed.png/64px-Rcode-button-task-crushed.png)
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