RosettaCodeData/Task/Canonicalize-CIDR/FreeBASIC/canonicalize-cidr.basic
2023-07-18 13:51:12 -07:00

54 lines
1.7 KiB
Text

#lang "qb"
REM THE Binary OPS ONLY WORK On SIGNED 16-Bit NUMBERS
REM SO WE STORE THE IP ADDRESS As AN ARRAY OF FOUR OCTETS
Cls
Dim IP(3)
Do
REM Read DEMO Data
140 Read CI$
If CI$ = "" Then Exit Do 'Sleep: End
REM FIND /
SL = 0
For I = Len(CI$) To 1 Step -1
If Mid$(CI$,I,1) = "/" Then SL = I : I = 1
Next I
If SL = 0 Then Print "INVALID CIDR STRING: '"; CI$; "'": Goto 140
NW = Val(Mid$(CI$,SL+1))
If NW < 1 Or NW > 32 Then Print "INVALID NETWORK WIDTH:"; NW: Goto 140
REM PARSE OCTETS INTO IP ARRAY
BY = 0 : N = 0
For I = 1 To SL-1
C$ = Mid$(CI$,I,1)
If Not (C$ <> ".") Then
IP(N) = BY : N = N + 1
BY = 0
If IP(N-1) < 256 Then 310
Print "INVALID OCTET VALUE:"; IP(N-1): Goto 140
Else C = Val(C$):If C Or (C$="0") Then BY = BY*10+C
End If
310 '
Next I
IP(N) = BY : N = N + 1
If IP(N-1) > 255 Then Print "INVALID OCTET VALUE:"; IP(N-1): Goto 140
REM NUMBER OF COMPLETE OCTETS IN NETWORK PART
NB = Int(NW/8)
REM NUMBER OF NETWORK BITS IN PARTIAL OCTET
XB = NW And 7
REM ZERO Out HOST BITS IN PARTIAL OCTET
IP(NB) = IP(NB) And (255 - 2^(8-XB) + 1)
REM And SET Any ALL-HOST OCTETS To 0
If NB < 3 Then For I = NB +1 To 3 : IP(I) = 0 : Next I
REM Print Out THE RESULT
Print Mid$(Str$(IP(0)),2);
For I = 1 To 3
Print "."; Mid$(Str$(IP( I)),2);
Next I
Print Mid$(CI$,SL)
Loop
Data "87.70.141.1/22", "36.18.154.103/12", "62.62.197.11/29"
Data "67.137.119.181/4", "161.214.74.21/24", "184.232.176.184/18"
REM SOME INVALID INPUTS
Data "127.0.0.1", "123.45.67.89/0", "98.76.54.32/100", "123.456.789.0/12"
Sleep