Data update
This commit is contained in:
parent
4bb20c9b71
commit
cbaf4c4b64
12390 changed files with 318560 additions and 27248 deletions
105
Task/Canonicalize-CIDR/Ada/canonicalize-cidr.adb
Normal file
105
Task/Canonicalize-CIDR/Ada/canonicalize-cidr.adb
Normal file
|
|
@ -0,0 +1,105 @@
|
|||
with Ada.Strings;
|
||||
with Ada.Strings.Fixed;
|
||||
with Ada.Strings.Maps;
|
||||
with Ada.Text_IO;
|
||||
|
||||
use Ada.Strings;
|
||||
use Ada.Strings.Fixed;
|
||||
use Ada.Strings.Maps;
|
||||
use Ada.Text_IO;
|
||||
|
||||
procedure Canonicalize_CIDR is
|
||||
type IP_Octet_Type is mod 256;
|
||||
|
||||
type IP_Record_Type is record
|
||||
A, B, C, D : IP_Octet_Type;
|
||||
end record
|
||||
with Size => 32;
|
||||
|
||||
for IP_Record_Type use record
|
||||
-- Use little-endian ordering to match bit array
|
||||
D at 0 range 0 .. 7;
|
||||
C at 1 range 0 .. 7;
|
||||
B at 2 range 0 .. 7;
|
||||
A at 3 range 0 .. 7;
|
||||
end record;
|
||||
|
||||
type IP_Bitarray_Type is array (0 .. 31) of Boolean
|
||||
with Component_Size => 1;
|
||||
|
||||
subtype IP_Mask_Type is Natural range 0 .. 32;
|
||||
|
||||
type IP_CIDR_Type is record
|
||||
IP : IP_Record_Type;
|
||||
Mask : IP_Mask_Type;
|
||||
end record;
|
||||
|
||||
function Parse_IP_CIDR (S : String) return IP_CIDR_Type is
|
||||
IP_Record : IP_CIDR_Type;
|
||||
Digit_Range : Character_Range := ('0', '9');
|
||||
Digit_Set : Character_Set := To_Set (Digit_Range);
|
||||
Octets : array (1 .. 4) of IP_Octet_Type;
|
||||
First : Positive;
|
||||
Last : Natural := 0;
|
||||
begin
|
||||
for I in Octets'Range loop
|
||||
Find_Token (S, Digit_Set, Last + 1, Inside, First, Last);
|
||||
Octets (I) := IP_Octet_Type'Value (S (First .. Last));
|
||||
end loop;
|
||||
IP_Record.IP.A := Octets (1);
|
||||
IP_Record.IP.B := Octets (2);
|
||||
IP_Record.IP.C := Octets (3);
|
||||
IP_Record.IP.D := Octets (4);
|
||||
|
||||
Find_Token (S, Digit_Set, Last + 1, Inside, First, Last);
|
||||
IP_Record.Mask := IP_Mask_Type'Value (S (First .. Last));
|
||||
|
||||
return IP_Record;
|
||||
end Parse_IP_CIDR;
|
||||
|
||||
procedure Canonicalize_IP_CIDR (Addr : in out IP_CIDR_Type) is
|
||||
-- Fun part. I can overlay different types over the same bits.
|
||||
Bit_Overlay : IP_Bitarray_Type with Address => Addr.IP'Address;
|
||||
begin
|
||||
for I in Bit_Overlay'First .. Bit_Overlay'Last - Addr.Mask loop
|
||||
Bit_Overlay (I) := False;
|
||||
end loop;
|
||||
end Canonicalize_IP_CIDR;
|
||||
|
||||
procedure Put_IP_CIDR (Addr : IP_CIDR_TYPE) is
|
||||
package Octet_IO is new Ada.Text_IO.Modular_IO (IP_Octet_Type);
|
||||
package Mask_IO is new Ada.Text_IO.Integer_IO (IP_Mask_Type);
|
||||
begin
|
||||
Octet_IO.Put (Addr.IP.A, 0);
|
||||
Put (".");
|
||||
Octet_IO.Put (Addr.IP.B, 0);
|
||||
Put (".");
|
||||
Octet_IO.Put (Addr.IP.C, 0);
|
||||
Put (".");
|
||||
Octet_IO.Put (Addr.IP.D, 0);
|
||||
Put ("/");
|
||||
Mask_IO.Put (Addr.Mask, 0);
|
||||
end Put_IP_CIDR;
|
||||
|
||||
procedure Show_IP_Canonicalize (S : String) is
|
||||
Canon : IP_CIDR_Type := Parse_IP_CIDR (S);
|
||||
begin
|
||||
Canonicalize_IP_Cidr (Canon);
|
||||
Put (S & " -> ");
|
||||
Put_IP_CIDR (Canon);
|
||||
New_Line;
|
||||
end Show_IP_Canonicalize;
|
||||
|
||||
Test_IPs : array (1 .. 5) of String (1 .. 18) :=
|
||||
(
|
||||
"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"
|
||||
);
|
||||
begin
|
||||
for I of Test_IPs loop
|
||||
Show_IP_Canonicalize (I);
|
||||
end loop;
|
||||
end Canonicalize_CIDR;
|
||||
132
Task/Canonicalize-CIDR/FutureBasic/canonicalize-cidr.basic
Normal file
132
Task/Canonicalize-CIDR/FutureBasic/canonicalize-cidr.basic
Normal file
|
|
@ -0,0 +1,132 @@
|
|||
//
|
||||
// Canonicalize CIDR
|
||||
//
|
||||
// Using FutureBasic 7.0.34
|
||||
// August 25, R.W
|
||||
//
|
||||
// Given a Classless Inter-Domain Routing (CIDR)
|
||||
// IPv4 address, returns the canonical form.
|
||||
//
|
||||
|
||||
Int networkWidth // network width in bits
|
||||
CFStringRef errorCode // global err and CCIDR
|
||||
CFStringRef CCIDR // canonical CIDR IPv4
|
||||
|
||||
// Type for IP address
|
||||
begin record IPv4_Address
|
||||
Int octets[3] // xxx.xxx.xxx.xx/xx
|
||||
end record
|
||||
|
||||
// Validate CIDR string
|
||||
local fn ValidateCIDR(ip as IPv4_Address, SnetworkWidth as Int, cidr as CFStringRef) as Boolean
|
||||
Int i
|
||||
boolean result
|
||||
result = _True
|
||||
if instr(0, cidr, @"/") == NSNotFound
|
||||
errorCode = concat(@"Bad CIDR ",cidr)
|
||||
result = _False
|
||||
return result
|
||||
end if
|
||||
if SnetworkWidth < 1 || SnetworkWidth > 32 //validate network width
|
||||
errorCode = concat(@"Bad Net Width",str(networkWidth))
|
||||
result = _False
|
||||
return result
|
||||
end if
|
||||
for i = 0 to 3
|
||||
if ip.octets[i] > 255
|
||||
errorCode = concat(@"Bad Octet ",str(ip.octets[i]))
|
||||
result = _False
|
||||
return result
|
||||
end if
|
||||
next
|
||||
end fn = result
|
||||
|
||||
// Check if a character is a digit
|
||||
local fn IsDigit(ch as CFStringRef) as boolean
|
||||
Boolean IsDigit
|
||||
IsDigit = (ucc(ch) > 47) && (ucc(ch) < 58)
|
||||
end fn = IsDigit
|
||||
|
||||
// Parse CIDR string into IP structure and network width
|
||||
local fn ParseIPv4_Address(cidr as CFStringRef) as IPv4_Address
|
||||
IPv4_Address ip
|
||||
Int i, slashPos, currentOctet, octetValue
|
||||
CFStringRef ipPart
|
||||
ipPart = @""
|
||||
slashPos = instr(0, cidr, @"/")
|
||||
if slashPos > 0
|
||||
ipPart = left(cidr, slashPos)
|
||||
networkWidth = Intval(mid(cidr, slashPos + 1))
|
||||
else
|
||||
ipPart = cidr
|
||||
networkWidth = -1
|
||||
end if
|
||||
currentOctet = 0: octetValue = 0
|
||||
for i = 0 to len(ipPart)-1
|
||||
select case mid(ipPart, i, 1)
|
||||
case @"."
|
||||
ip.octets[currentOctet] = octetValue
|
||||
currentOctet ++
|
||||
octetValue = 0
|
||||
case else
|
||||
if fn IsDigit(mid(ipPart, i, 1))
|
||||
octetValue = octetValue * 10 + Intval(mid(ipPart, i, 1))
|
||||
end if
|
||||
end select
|
||||
next
|
||||
ip.octets[currentOctet] = octetValue
|
||||
end fn = ip
|
||||
|
||||
// Apply network mask to IP
|
||||
local fn ApplyNetworkMask(ip as IPv4_Address, SnetworkWidth as Int) as IPv4_Address
|
||||
IPv4_Address result
|
||||
Int completeOctets, remainingBits, i
|
||||
result = ip
|
||||
completeOctets = SnetworkWidth \ 8 //octet bits
|
||||
remainingBits = SnetworkWidth AND 7
|
||||
if completeOctets < 4
|
||||
result.octets[completeOctets] = result.octets[completeOctets] AND (255 - 2^(8 - remainingBits) + 1)
|
||||
for i = completeOctets + 1 to 3
|
||||
result.octets[i] = 0
|
||||
next
|
||||
end if
|
||||
end fn = result
|
||||
|
||||
// Process a CIDR string, sets global CCIDR
|
||||
local fn ProcessCIDR(cidr as CFStringRef) as CFStringRef
|
||||
IPv4_Address ip
|
||||
CFStringRef result
|
||||
Int i
|
||||
result = @""
|
||||
ip = fn ParseIPv4_Address(cidr)
|
||||
if fn ValidateCIDR(ip, networkWidth, cidr) // validate
|
||||
ip = fn ApplyNetworkMask(ip, networkWidth)
|
||||
result = mid(str(ip.octets[0]),1)
|
||||
for i = 1 to 3
|
||||
result = concat(result,@".",mid(str(ip.octets[i]),1))
|
||||
next
|
||||
result = concat(result,@"/",mid(str(networkWidth),1))
|
||||
else
|
||||
print@ errorCode
|
||||
end if
|
||||
CCIDR = result
|
||||
end fn = result
|
||||
|
||||
//
|
||||
// Main
|
||||
|
||||
Window 1,@"Canonicalize CIDR"
|
||||
print@
|
||||
|
||||
// Test data from the Rosetta Stone task
|
||||
|
||||
CFStringRef cidr(5) = {@"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"}
|
||||
|
||||
for Int i = 0 to 5
|
||||
print@ fn ProcessCIDR(cidr(i))
|
||||
next
|
||||
|
||||
HandleEvents
|
||||
|
||||
//
|
||||
35
Task/Canonicalize-CIDR/Pluto/canonicalize-cidr.pluto
Normal file
35
Task/Canonicalize-CIDR/Pluto/canonicalize-cidr.pluto
Normal file
|
|
@ -0,0 +1,35 @@
|
|||
local fmt = require "fmt"
|
||||
|
||||
-- Canonicalize a CIDR block: make sure none of the host bits are set.
|
||||
local function canonicalize(cidr)
|
||||
-- Dotted-decimal / bits in network part.
|
||||
local split = cidr:split("/")
|
||||
local dotted = split[1]
|
||||
local size = tonumber(split[2])
|
||||
|
||||
-- Get IP as binary string.
|
||||
local binary = dotted:split("."):map(|n| -> fmt.lpad(fmt.bin(tonumber(n)), 8, "0")):concat()
|
||||
|
||||
-- Replace the host part with all zeros.
|
||||
binary = binary:sub(1, size) .. string.rep("0", 32 - size)
|
||||
|
||||
-- Convert back to dotted-decimal.
|
||||
local chunks = binary:split(""):chunk(8):map(|c| -> c:concat())
|
||||
local canon = chunks:map(|c| -> tonumber(c, 2)):concat(".")
|
||||
|
||||
-- And return
|
||||
return canon .. "/" .. split[2]
|
||||
end
|
||||
|
||||
local 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"
|
||||
}
|
||||
|
||||
for tests as test do
|
||||
fmt.print("%-18s -> %s", test, canonicalize(test))
|
||||
end
|
||||
47
Task/Canonicalize-CIDR/V-(Vlang)/canonicalize-cidr.v
Normal file
47
Task/Canonicalize-CIDR/V-(Vlang)/canonicalize-cidr.v
Normal file
|
|
@ -0,0 +1,47 @@
|
|||
import strconv
|
||||
import log
|
||||
|
||||
// canonicalize a CIDR block: make sure none of the host bits are set
|
||||
fn canonicalize(cidr string) string {
|
||||
mut l := log.Log{}
|
||||
mut binary := ""
|
||||
mut ir := 0
|
||||
mut num := i64(0)
|
||||
mut bin, mut canon := []string{}, []string{}
|
||||
|
||||
// dotted-decimal / bits in network part
|
||||
split_arr := cidr.split("/")
|
||||
dotted := split_arr[0]
|
||||
size := strconv.atoi(split_arr[1]) or {l.fatal('fatal 1')}
|
||||
|
||||
// get IP as binary string
|
||||
for n in dotted.split(".") {
|
||||
ir = strconv.atoi(n) or {l.fatal('fatal 2')}
|
||||
bin << "${ir:08b}"
|
||||
}
|
||||
|
||||
// replace the host part with all zeros
|
||||
binary = bin.join("")[0..size] + "0".repeat(32 - size)
|
||||
|
||||
// convert back to dotted-decimal
|
||||
for i := 0; i < binary.len; i += 8 {
|
||||
num = strconv.parse_int(binary[i..i + 8], 2, 64) or {l.fatal('fatal 3')}
|
||||
canon << "${num}"
|
||||
}
|
||||
|
||||
// and return
|
||||
return canon.join(".") + "/" + split_arr[1]
|
||||
}
|
||||
|
||||
fn main() {
|
||||
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"]
|
||||
|
||||
for test in tests {
|
||||
println("${test:-18} -> ${canonicalize(test)}")
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue