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
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