Canonicalize CIDR: Difference between revisions

m
Automated syntax highlighting fixup (second round - minor fixes)
m (syntax highlighting fixup automation)
m (Automated syntax highlighting fixup (second round - minor fixes))
Line 31:
{{trans|C}}
 
<syntaxhighlight lang="11l">F cidr_parse(str)
V (addr_str, m_str) = str.split(‘/’)
V (a, b, c, d) = addr_str.split(‘.’).map(Int)
Line 74:
184.232.176.184/18 -> 184.232.128.0/18
</pre>
 
=={{header|ALGOL 68}}==
<syntaxhighlight lang="algol68">BEGIN # show IPv4 addresses in CIDR notation in canonical form #
# mode to hold an IPv4 address in CIDR notation #
MODE CIDR = STRUCT( BITS address
Line 206 ⟶ 205:
184.232.176.184/18 -> 184.232.128.0/18
</pre>
 
=={{header|APL}}==
{{works with|Dyalog APL}}
<syntaxhighlight lang="apl"> canonicalize←{
nums←(2⊃⎕VFI)¨(~⍵∊'./')⊆⍵
ip len←(4↑nums)(5⊃nums)
Line 218 ⟶ 216:
}</syntaxhighlight>
{{out}}
<syntaxhighlight lang="apl"> canonicalize '87.70.141.1/22'
87.70.140.0/22</syntaxhighlight>
 
=={{header|C}}==
This solution uses only the standard library. On POSIX platforms one can use the functions
inet_pton/inet_ntop to parse/format IPv4 addresses.
<syntaxhighlight lang="c">#include <stdbool.h>
#include <stdio.h>
#include <stdint.h>
Line 298 ⟶ 295:
184.232.176.184/18 -> 184.232.128.0/18
</pre>
=={{header|C sharp|C#}}==
<syntaxhighlight lang="csharp">using System;
using System.Net;
using System.Linq;
public class Program
{
public static void Main()
{
string[] tests = {
"87.70.141.1/22",
"36.18.154.103/12",
"62.62.197.11/29",
"67.137.119.181/4",
"161.214.74.21/24",
"184.232.176.184/18"
};
foreach (string t in tests) Console.WriteLine($"{t} => {Canonicalize(t)}");
}
static string Canonicalize(string cidr) => CIDR.Parse(cidr).Canonicalize().ToString();
}
 
readonly struct CIDR
{
public readonly IPAddress ip;
public readonly int length;
public static CIDR Parse(string cidr)
{
string[] parts = cidr.Split('/');
return new CIDR(IPAddress.Parse(parts[0]), int.Parse(parts[1]));
}
public CIDR(IPAddress ip, int length) => (this.ip, this.length) = (ip, length);
public CIDR Canonicalize() =>
new CIDR(
new IPAddress(
ToBytes(
ToInt(
ip.GetAddressBytes()
)
& ~((1 << (32 - length)) - 1)
)
),
length
);
private int ToInt(byte[] bytes) => bytes.Aggregate(0, (n, b) => (n << 8) | b);
private byte[] ToBytes(int n)
{
byte[] bytes = new byte[4];
for (int i = 3; i >= 0; i--) {
bytes[i] = (byte)(n & 0xFF);
n >>= 8;
}
return bytes;
}
public override string ToString() => $"{ip}/{length}";
}</syntaxhighlight>
{{out}}
<pre>
87.70.141.1/22 => 87.70.140.0/22
36.18.154.103/12 => 36.16.0.0/12
62.62.197.11/29 => 62.62.197.8/29
67.137.119.181/4 => 64.0.0.0/4
161.214.74.21/24 => 161.214.74.0/24
184.232.176.184/18 => 184.232.128.0/18</pre>
=={{header|C++}}==
<syntaxhighlight lang="cpp">#include <cstdint>
#include <iomanip>
#include <iostream>
Line 388 ⟶ 456:
184.232.176.184/18 -> 184.232.128.0/18
</pre>
 
=={{header|C sharp|C#}}==
<syntaxhighlight lang=csharp>using System;
using System.Net;
using System.Linq;
public class Program
{
public static void Main()
{
string[] tests = {
"87.70.141.1/22",
"36.18.154.103/12",
"62.62.197.11/29",
"67.137.119.181/4",
"161.214.74.21/24",
"184.232.176.184/18"
};
foreach (string t in tests) Console.WriteLine($"{t} => {Canonicalize(t)}");
}
static string Canonicalize(string cidr) => CIDR.Parse(cidr).Canonicalize().ToString();
}
 
readonly struct CIDR
{
public readonly IPAddress ip;
public readonly int length;
public static CIDR Parse(string cidr)
{
string[] parts = cidr.Split('/');
return new CIDR(IPAddress.Parse(parts[0]), int.Parse(parts[1]));
}
public CIDR(IPAddress ip, int length) => (this.ip, this.length) = (ip, length);
public CIDR Canonicalize() =>
new CIDR(
new IPAddress(
ToBytes(
ToInt(
ip.GetAddressBytes()
)
& ~((1 << (32 - length)) - 1)
)
),
length
);
private int ToInt(byte[] bytes) => bytes.Aggregate(0, (n, b) => (n << 8) | b);
private byte[] ToBytes(int n)
{
byte[] bytes = new byte[4];
for (int i = 3; i >= 0; i--) {
bytes[i] = (byte)(n & 0xFF);
n >>= 8;
}
return bytes;
}
public override string ToString() => $"{ip}/{length}";
}</syntaxhighlight>
{{out}}
<pre>
87.70.141.1/22 => 87.70.140.0/22
36.18.154.103/12 => 36.16.0.0/12
62.62.197.11/29 => 62.62.197.8/29
67.137.119.181/4 => 64.0.0.0/4
161.214.74.21/24 => 161.214.74.0/24
184.232.176.184/18 => 184.232.128.0/18</pre>
 
=={{header|Commodore BASIC}}==
<syntaxhighlight lang="gwbasic">100 REM THE BINARY OPS ONLY WORK ON SIGNED 16-BIT NUMBERS
110 REM SO WE STORE THE IP ADDRESS AS AN ARRAY OF FOUR OCTETS
120 DIM IP(3)
Line 521 ⟶ 515:
READY.</pre>
=={{header|Common Lisp}}==
<syntaxhighlight lang="lisp">(defun ip->bit-vector (ip)
(flet ((int->bits (int)
(loop :for i :below 8
Line 563 ⟶ 557:
161.214.74.21/24 → 161.214.74.0/24
184.232.176.184/18 → 184.232.128.0/18</pre>
 
=={{header|Cowgol}}==
<syntaxhighlight lang="cowgol">include "cowgol.coh";
 
typedef IP is uint32;
Line 650 ⟶ 643:
<pre>Before canonicalization: 87.70.141.1/22
After canonicalization: 87.70.140.0/22</pre>
 
=={{header|Factor}}==
{{trans|Ruby}}
{{works with|Factor|0.99 2020-07-03}}
<syntaxhighlight lang="factor">USING: command-line formatting grouping io kernel math.parser
namespaces prettyprint sequences splitting ;
IN: rosetta-code.canonicalize-cidr
Line 681 ⟶ 673:
87.70.140.0/22
</pre>
 
=={{header|Go}}==
{{trans|Ruby}}
<syntaxhighlight lang="go">package main
 
import (
Line 755 ⟶ 746:
184.232.176.184/18 -> 184.232.128.0/18
</pre>
 
=={{header|Hare}}==
<syntaxhighlight lang="hare">use fmt;
use net::ip;
use strings;
Line 810 ⟶ 800:
184.232.176.184/18 => 184.232.128.0/18
</pre>
 
=={{header|Haskell}}==
This is implemented using only libraries found in the base package.
<syntaxhighlight lang="haskell">import Control.Monad (guard)
import Data.Bits ((.|.), (.&.), complement, shiftL, shiftR, zeroBits)
import Data.Maybe (listToMaybe)
Line 904 ⟶ 893:
184.232.184/18 -> invalid CIDR string
</pre>
 
=={{header|J}}==
 
Implementation:
 
<syntaxhighlight lang=J"j">cidr=: {{
'a e'=. 0 ".each (y rplc'. ')-.&;:'/'
('/',":e),~rplc&' .'":_8#.\32{.e{.,(8#2)#:a
Line 918 ⟶ 906:
Task examples:
 
<syntaxhighlight lang=J"j"> cidr '87.70.141.1/22'
87.70.140.0/22
cidr '36.18.154.103/12'
Line 930 ⟶ 918:
cidr '184.232.176.184/18'
184.232.128.0/18</syntaxhighlight>
 
=={{header|Java}}==
<syntaxhighlight lang="java">import java.text.MessageFormat;
import java.text.ParseException;
 
Line 1,008 ⟶ 995:
184.232.176.184/18 -> 184.232.128.0/18
</pre>
 
=={{header|JavaScript}}==
<syntaxhighlight lang="javascript">const canonicalize = s => {
 
// Prepare a DataView over a 16 Byte Array buffer.
Line 1,074 ⟶ 1,060:
10.../8 -> 10.0.0.0/8
</pre>
 
=={{header|Julia}}==
Julia has a Sockets library as a builtin, which has the types IPv4 and IPv6 for single IP addresses.
<syntaxhighlight lang="julia">using Sockets
 
function canonCIDR(cidr::String)
Line 1,107 ⟶ 1,092:
10.0.0.0/8
</pre>
 
=={{header|Lua}}==
{{libheader|inet}}
<syntaxhighlight lang="lua">inet = require 'inet'
 
test_cases = {
Line 1,128 ⟶ 1,112:
161.214.74.0/24
184.232.128.0/18</pre>
 
=={{header|Mathematica}}/{{header|Wolfram Language}}==
<syntaxhighlight lang=Mathematica"mathematica">ClearAll[CanonicalizeCIDR]
CanonicalizeCIDR[str_String] := Module[{i, ip, chop, keep, change},
If[StringMatchQ[str, "*.*.*.*/*"],
Line 1,165 ⟶ 1,148:
161.214.74.0/24
184.232.128.0/18</pre>
 
=={{header|Nim}}==
Using the IpAddress type from standard module “net”.
<syntaxhighlight lang=Nim"nim">import net
import strutils
 
Line 1,233 ⟶ 1,215:
161.214.74.21/24 ⇢ 161.214.74.0/24
184.232.176.184/18 ⇢ 184.232.128.0/18</pre>
 
=={{header|Perl}}==
There's a CPAN module for IP address manipulation, <tt>Net::IP</tt>. Unfortunately, it requires a CIDR string to be already in canonical form; otherwise it fails with an "Invalid prefix" error. So we do it manually.
<syntaxhighlight lang="perl">#!/usr/bin/env perl
use v5.16;
use Socket qw(inet_aton inet_ntoa);
Line 1,265 ⟶ 1,246:
<pre>$ canonicalize_cidr.pl 87.70.141.1/22
87.70.140.0/22</pre>
 
=={{header|Phix}}==
<!--<syntaxhighlight lang=Phix"phix">(phixonline)-->
<span style="color: #008080;">with</span> <span style="color: #008080;">javascript_semantics</span> <span style="color: #000080;font-style:italic;">-- (not likely useful)</span>
<span style="color: #008080;">function</span> <span style="color: #000000;">canonicalize_cidr</span><span style="color: #0000FF;">(</span><span style="color: #004080;">string</span> <span style="color: #000000;">cidr</span><span style="color: #0000FF;">)</span>
Line 1,311 ⟶ 1,291:
184.232.176.184/18 -> 184.232.128.0/18
</pre>
 
=={{header|PicoLisp}}==
<syntaxhighlight lang=PicoLisp"picolisp">(de cidr (S)
(let
(L (rot (mapcar format (split (chop S) "." "/")))
Line 1,350 ⟶ 1,329:
184.232.176.184/18 => 184.232.128.0/18
</pre>
 
=={{header|Python}}==
{{trans|Perl}}
<syntaxhighlight lang="python">#!/usr/bin/env python
# canonicalize a CIDR block specification:
# make sure none of the host bits are set
Line 1,386 ⟶ 1,364:
 
===Bit mask and shift===
<syntaxhighlight lang="python">"""Canonicalize CIDR"""
DIGITS = (24, 16, 8, 0)
 
Line 1,439 ⟶ 1,417:
The <code>ipaddress</code> module was added in Python version 3.3.
 
<syntaxhighlight lang="python">import ipaddress
 
def canonicalize(address: str) -> str:
Line 1,467 ⟶ 1,445:
184.232.176.184/18 -> 184.232.128.0/18
</pre>
 
=={{header|Raku}}==
===Using library===
{{libheader|raku-IP-Addr}}
<syntaxhighlight lang="raku" line>use IP::Addr;
for «87.70.141.1/22 36.18.154.103/12 62.62.197.11/29 67.137.119.181/4 161.214.74.21/24 184.232.176.184/18» -> $cidr {
say "$cidr -> $(IP::Addr.new($cidr).network)";
Line 1,478 ⟶ 1,455:
===String manipulation===
{{trans|Perl}}
<syntaxhighlight lang="raku" line>#!/usr/bin/env raku
unit sub MAIN(*@cidrs);
 
Line 1,517 ⟶ 1,494:
 
===Bit mask and shift===
<syntaxhighlight lang="raku" line># canonicalize a IP4 CIDR block
sub CIDR-IP4-canonicalize ($address) {
constant @mask = 24, 16, 8, 0;
Line 1,566 ⟶ 1,543:
CIDR: 10.11.12.13/8 Routing prefix: 10.0.0.0/8
CIDR: 10.../8 Routing prefix: 10.0.0.0/8</pre>
 
=={{header|REXX}}==
<syntaxhighlight lang="rexx">/*REXX pgm canonicalizes IPv4 addresses that are in CIDR notation (dotted─dec/network).*/
parse arg a . /*obtain optional argument from the CL.*/
if a=='' | a=="," then a= '87.70.141.1/22' , /*Not specified? Then use the defaults*/
Line 1,620 ⟶ 1,596:
canonicalized address: 184.232.128.0/18
</pre>
 
=={{header|Ruby}}==
{{trans|Python}}
{{trans|Raku}}
 
<syntaxhighlight lang="ruby">#!/usr/bin/env ruby
 
# canonicalize a CIDR block: make sure none of the host bits are set
Line 1,655 ⟶ 1,630:
87.70.140.0/22</pre>
===Built in===
<syntaxhighlight lang="ruby">
require "ipaddr"
Line 1,674 ⟶ 1,649:
161.214.74.0/24
184.232.128.0/18</pre>
 
=={{header|Rust}}==
<syntaxhighlight lang=Rust"rust">use std::net::Ipv4Addr;
 
fn canonical_cidr(cidr: &str) -> Result<String, &str> {
Line 1,715 ⟶ 1,689:
println!("{}", canonical_cidr("127.1.2.3/24").unwrap());
}</syntaxhighlight>
 
=={{header|SNOBOL}}==
<syntaxhighlight lang="snobol">* Pattern to match any number of digits
D = SPAN('0123456789')
 
Line 1,773 ⟶ 1,746:
161.214.74.0/24
184.232.128.0/18</pre>
 
=={{header|UNIX Shell}}==
{{works with|Bourne Again SHell}}
{{works with|Korn Shell}}
{{works with|Zsh}}
<syntaxhighlight lang="bash">function inet_aton {
typeset -i addr byte
typeset -a bytes
Line 1,829 ⟶ 1,801:
161.214.74.0/24
184.232.128.0/18</pre>
 
=={{header|Wren}}==
{{trans|Ruby}}
{{libheader|Wren-fmt}}
{{libheader|Wren-str}}
<syntaxhighlight lang="ecmascript">import "/fmt" for Fmt, Conv
import "/str" for Str
 
10,327

edits