Canonicalize CIDR: Difference between revisions
Content added Content deleted
(Create task and add initial implementations.) |
|||
Line 28: | Line 28: | ||
87.70.140.0/22</pre> |
87.70.140.0/22</pre> |
||
=={header|Python}}== |
=={{header|Python}}== |
||
{{trans|Perl}} |
{{trans|Perl}} |
||
<lang python> |
<lang python> |
Revision as of 03:52, 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) {
my ($dotted, $size) = split m#/#; my $binary = sprintf "%032b", unpack('N', inet_aton($dotted)); substr($binary,$size) = "0" x (32 - $size); $dotted = inet_ntoa(pack('B32', $binary)); 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