Canonicalize CIDR: Difference between revisions

Add Swift implementation
(Add Scala implementation)
(Add Swift implementation)
 
(4 intermediate revisions by 3 users not shown)
Line 41:
| d < 0 | d > 255
R (0, 0)
V mask = (-)~((1 << (32 - m)) - 1)
V address = (a << 24) + (b << 16) + (c << 8) + d
address [&]= mask
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 #
Line 812 ⟶ 813:
<pre>Before canonicalization: 87.70.141.1/22
After canonicalization: 87.70.140.0/22</pre>
=={{header|EasyLang}}==
<syntaxhighlight>
func$ can_cidr s$ .
n[] = number strsplit s$ "./"
if len n[] <> 5
return ""
.
for i to 4
if n[i] < 0 or n[i] > 255
return ""
.
ad = ad * 256 + n[i]
.
if n[5] > 31 or n[5] < 1
return ""
.
mask = bitnot (bitshift 1 (32 - n[5]) - 1)
ad = bitand ad mask
for i to 4
if r$ <> ""
r$ = "." & r$
.
r$ = ad mod 256 & r$
ad = ad div 256
.
return r$ & "/" & n[5]
.
repeat
s$ = input
until s$ = ""
print s$ & " -> " & can_cidr s$
.
#
input_data
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
 
</syntaxhighlight>
 
=={{header|Factor}}==
{{trans|Ruby}}
Line 842 ⟶ 886:
87.70.140.0/22
</pre>
 
=={{header|Go}}==
{{trans|Ruby}}
Line 1,397 ⟶ 1,442:
161.214.74.0/24
184.232.128.0/18</pre>
 
=={{header|MATLAB}}==
{{trans|Python}}
<syntaxhighlight lang="MATLAB">
clear all;close all;clc;
cidrCanonicalizer();
 
function cidrCanonicalizer
% Main function to test CIDR canonicalization
% Define test cases
testCases = {
'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'
};
% Run test cases
for i = 1:size(testCases, 1)
ip = testCases{i, 1};
expected = testCases{i, 2};
result = canonicalize(ip);
fprintf('%s -> %s\n', ip, result);
assert(strcmp(result, expected));
end
end
 
function result = dottedToInt(dotted)
% Convert dotted IP to integer representation
parts = str2double(strsplit(dotted, '.'));
result = sum(parts .* (256 .^ (3:-1:0)));
end
 
function result = intToDotted(ip)
% Convert integer IP to dotted representation
result = strjoin(arrayfun(@(x) num2str(bitshift(bitand(ip, bitshift(255, x)), -x)), [24 16 8 0], 'UniformOutput', false), '.');
end
 
function result = networkMask(numberOfBits)
% Create a network mask for the given number of bits
result = bitshift((bitshift(1, numberOfBits) - 1), (32 - numberOfBits));
end
 
function result = canonicalize(ip)
% Canonicalize the given CIDR IP
[dotted, networkBits] = strtok(ip, '/');
networkBits = str2double(strrep(networkBits, '/', ''));
i = dottedToInt(dotted);
mask = networkMask(networkBits);
result = strcat(intToDotted(bitand(i, mask)), '/', num2str(networkBits));
end
</syntaxhighlight>
{{out}}
<pre>
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|Nim}}==
Using the IpAddress type from standard module “net”.
Line 2,140 ⟶ 2,248:
161.214.74.0/24
184.232.128.0/18</pre>
 
=={{header|Swift}}==
{{trans|Python}}
<syntaxhighlight lang="Swift">
import Foundation
 
func dottedToInt(_ dotted: String) -> UInt32 {
let digits = dotted.split(separator: ".").map { UInt32($0)! }
return digits.enumerated().reduce(0) { $0 + ($1.element << (24 - $1.offset * 8)) }
}
 
func intToDotted(_ ip: UInt32) -> String {
let digits = [24, 16, 8, 0].map { (ip & (255 << $0)) >> $0 }
return digits.map { String($0) }.joined(separator: ".")
}
 
func networkMask(_ numberOfBits: Int) -> UInt32 {
// Explicitly use UInt32 for bitwise operations
return UInt32((1 << numberOfBits) - 1) << (32 - numberOfBits)
}
 
func canonicalize(_ ip: String) -> String {
let parts = ip.split(separator: "/")
let dotted = String(parts[0])
let networkBits = Int(parts[1])!
let i = dottedToInt(dotted)
let mask = networkMask(networkBits)
return "\(intToDotted(i & mask))/\(networkBits)"
}
 
let testCases = [
("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"),
]
 
for testCase in testCases {
let (ip, expect) = testCase
let result = canonicalize(ip)
print("\(ip) -> \(result)")
assert(result == expect, "Test failed for \(ip)")
}
</syntaxhighlight>
{{out}}
<pre>
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|Tcl}}==
{{trans|Python}}
<syntaxhighlight lang="Tcl">
# Canonicalize CIDR in Tcl
 
# Convert dotted IP address to integer
proc dotted_to_int {dotted} {
set digits [split $dotted .]
set result 0
foreach digit $digits {
set result [expr {$result * 256 + $digit}]
}
return $result
}
 
# Convert integer IP address to dotted format
proc int_to_dotted {ip} {
set result {}
for {set i 3} {$i >= 0} {incr i -1} {
lappend result [expr {($ip >> ($i * 8)) & 0xFF}]
}
return [join $result .]
}
 
# Calculate network mask
proc network_mask {number_of_bits} {
return [expr {(1 << $number_of_bits) - 1 << (32 - $number_of_bits)}]
}
 
# Canonicalize IP address
proc canonicalize {ip} {
regexp {^(.*)/(.*)$} $ip -> dotted network_bits
set i [dotted_to_int $dotted]
set mask [network_mask $network_bits]
return [int_to_dotted [expr {$i & $mask}]]/$network_bits
}
 
# Test cases
set test_cases {
{"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"}
}
 
# Main execution
foreach test $test_cases {
foreach {ip expect} $test {}
set rv [canonicalize $ip]
puts "$ip -> $rv"
if {$rv ne $expect} {
error "Test failed: $rv != $expect"
}
}
</syntaxhighlight>
{{out}}
<pre>
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|TXR}}==
 
337

edits