Canonicalize CIDR: Difference between revisions
Content added Content deleted
(→{{header|Perl}}: Add comments, remove some extraneous parens.) |
(→{{header|Python}}: trim whitespace) |
||
Line 37: | Line 37: | ||
=={{header|Python}}== |
=={{header|Python}}== |
||
{{trans|Perl}} |
{{trans|Perl}} |
||
<lang python> |
<lang python>#!/usr/bin/env python |
||
#!/usr/bin/env python |
|||
# canonicalize a CIDR block specification: |
# canonicalize a CIDR block specification: |
||
# make sure none of the host bits are set |
# make sure none of the host bits are set |
||
Line 62: | Line 61: | ||
canon_dotted = inet_ntoa(pack('!I', |
canon_dotted = inet_ntoa(pack('!I', |
||
(canon_numeric))) # and then to dotted-decimal |
(canon_numeric))) # and then to dotted-decimal |
||
print(f'{canon_dotted}/{size}') # output result |
print(f'{canon_dotted}/{size}') # output result</lang> |
||
</lang> |
|||
{{Out}} |
{{Out}} |
||
<pre>$ canonicalize_cidr.py 87.70.141.1/22 |
<pre>$ canonicalize_cidr.py 87.70.141.1/22 |
Revision as of 03:55, 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