RosettaCodeData/Task/Canonicalize-CIDR/FreeBASIC/canonicalize-cidr.basic
2025-02-27 18:35:13 -05:00

99 lines
2.7 KiB
Text

Const MAX_OCTET = 255
Const MIN_NETWORK = 1
Const MAX_NETWORK = 32
Const OCTET_BITS = 8
Type IPAddress
octets(3) As Integer
End Type
Function isDigit(Byval ch As String) As Boolean
Return (Asc(ch) >= Asc("0")) And (Asc(ch) <= Asc("9"))
End Function
Function ParseIPAddress(cidr As String, Byref networkWidth As Integer) As IPAddress
Dim As IPAddress ip
Dim As Integer slashPos = Instr(cidr, "/")
Dim As String ipPart = Left(cidr, slashPos - 1)
networkWidth = Val(Mid(cidr, slashPos + 1))
Dim As Integer i, currentOctet = 0, octetValue = 0
For i = 1 To Len(ipPart)
If Mid(ipPart, i, 1) = "." Then
ip.octets(currentOctet) = octetValue
currentOctet += 1
octetValue = 0
Elseif IsDigit(Mid(ipPart, i, 1)) Then
octetValue = octetValue * 10 + Val(Mid(ipPart, i, 1))
End If
Next
ip.octets(currentOctet) = octetValue
Return ip
End Function
Function ApplyNetworkMask(ip As IPAddress, networkWidth As Integer) As IPAddress
Dim As IPAddress result = ip
Dim As Integer completeOctets = networkWidth \ OCTET_BITS
Dim As Integer remainingBits = networkWidth And 7
' Apply mask to partial octet
If completeOctets < 4 Then
result.octets(completeOctets) And= (MAX_OCTET - 2^(OCTET_BITS-remainingBits) + 1)
' Zero remaining octets
For i As Integer = completeOctets + 1 To 3
result.octets(i) = 0
Next
End If
Return result
End Function
Function ValidateInput(ip As IPAddress, networkWidth As Integer, cidr As String) As Boolean
If Instr(cidr, "/") = 0 Then
Print "INVALID CIDR STRING: '"; cidr; "'"
Return False
End If
If networkWidth < MIN_NETWORK Or networkWidth > MAX_NETWORK Then
Print "INVALID NETWORK WIDTH:"; networkWidth
Return False
End If
For i As Integer = 0 To 3
If ip.octets(i) > MAX_OCTET Then
Print "INVALID OCTET VALUE:"; ip.octets(i)
Return False
End If
Next
Return True
End Function
Sub ProcessCIDR(cidr As String)
Dim As Integer networkWidth
Dim As IPAddress ip = ParseIPAddress(cidr, networkWidth)
If Not ValidateInput(ip, networkWidth, cidr) Then Exit Sub
ip = ApplyNetworkMask(ip, networkWidth)
Dim As String result = Str(ip.octets(0))
For i As Integer = 1 To 3
result &= "." & Str(ip.octets(i))
Next
Print result & "/" & networkWidth
End Sub
' Main program
Dim As String cidr(9) = { _
"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", _
"127.0.0.1", "123.45.67.89/0", "98.76.54.32/100", "123.456.789.0/12" }
For i As Integer = 0 To 9
ProcessCIDR(cidr(i))
Next
Sleep