Another update from ingydotnet^djgoku
This commit is contained in:
parent
91df62d461
commit
948b86eafa
7604 changed files with 108452 additions and 22726 deletions
113
Task/Parse-an-IP-Address/Haskell/parse-an-ip-address.hs
Normal file
113
Task/Parse-an-IP-Address/Haskell/parse-an-ip-address.hs
Normal file
|
|
@ -0,0 +1,113 @@
|
|||
import Data.List (isInfixOf)
|
||||
import Numeric (showHex)
|
||||
import Data.Char (isDigit)
|
||||
|
||||
data IPChunk = IPv6Chunk String | IPv4Chunk (String, String) |
|
||||
IPv6WithPort [IPChunk] String | IPv6NoPort [IPChunk] |
|
||||
IPv4WithPort IPChunk String | IPv4NoPort IPChunk |
|
||||
IPInvalid | IPZeroSection | IPUndefinedWithPort String |
|
||||
IPUndefinedNoPort
|
||||
|
||||
instance Show IPChunk where
|
||||
show (IPv6Chunk a) = a
|
||||
show (IPv4Chunk (a,b)) = a ++ b
|
||||
show (IPv6WithPort a p) = "IPv6 " ++ concatMap show a ++ " port " ++ p
|
||||
show (IPv6NoPort a) = "IPv6 " ++ concatMap show a ++ " no port"
|
||||
show (IPv4WithPort a p) = "IPv4 " ++ show a ++ " port " ++ p
|
||||
show (IPv4NoPort a) = "IPv4 " ++ show a
|
||||
show IPInvalid = "Invalid IP address"
|
||||
|
||||
isIPInvalid IPInvalid = True
|
||||
isIPInvalid _ = False
|
||||
|
||||
isIPZeroSection IPZeroSection = True
|
||||
isIPZeroSection _ = False
|
||||
|
||||
splitOn _ [] = []
|
||||
splitOn x xs = let (a, b) = break (== x) xs in a : splitOn x (drop 1 b)
|
||||
|
||||
count x = length . filter (== x)
|
||||
|
||||
between a b x = x >= a && x <= b
|
||||
|
||||
none f = all (not . f)
|
||||
|
||||
parse1 [] = IPInvalid
|
||||
parse1 "::" = IPUndefinedNoPort
|
||||
parse1 ('[':':':':':']':':':ps) = if portIsValid ps then IPUndefinedWithPort ps else IPInvalid
|
||||
parse1 ('[':xs) = if "]:" `isInfixOf` xs
|
||||
then let (a, b) = break (== ']') xs in
|
||||
if tail b == ":" then IPInvalid else IPv6WithPort (map chunk (splitOn ':' a)) (drop 2 b)
|
||||
else IPInvalid
|
||||
parse1 xs
|
||||
| count ':' xs <= 1 && count '.' xs == 3 =
|
||||
let (a, b) = break (== ':') xs in case b of
|
||||
"" -> IPv4NoPort (chunk a)
|
||||
(':':ps) -> IPv4WithPort (chunk a) ps
|
||||
_ -> IPInvalid
|
||||
| count ':' xs > 1 && count '.' xs <= 3 =
|
||||
IPv6NoPort (map chunk (splitOn ':' xs))
|
||||
|
||||
chunk [] = IPZeroSection
|
||||
chunk xs
|
||||
| '.' `elem` xs = case splitOn '.' xs of
|
||||
[a,b,c,d] -> let [e,f,g,h] = map read [a,b,c,d]
|
||||
in if all (between 0 255) [e,f,g,h]
|
||||
then let [i,j,k,l] = map (\n -> fill 2 $ showHex n "") [e,f,g,h]
|
||||
in IPv4Chunk (i ++ j, k ++ l)
|
||||
else IPInvalid
|
||||
| ':' `notElem` xs && between 1 4 (length xs) && all (`elem` "0123456789abcdef") xs = IPv6Chunk (fill 4 xs)
|
||||
| otherwise = IPInvalid
|
||||
|
||||
fill n xs = replicate (n - length xs) '0' ++ xs
|
||||
|
||||
parse2 IPInvalid = IPInvalid
|
||||
parse2 (IPUndefinedWithPort p) = IPv6WithPort (replicate 8 zeroChunk) p
|
||||
parse2 IPUndefinedNoPort = IPv6NoPort (replicate 8 zeroChunk)
|
||||
parse2 a = case a of
|
||||
IPv6WithPort xs p -> if none isIPInvalid xs && portIsValid p
|
||||
then let ys = complete xs
|
||||
in if countChunks ys == 8
|
||||
then IPv6WithPort ys p
|
||||
else IPInvalid
|
||||
else IPInvalid
|
||||
IPv6NoPort xs -> if none isIPInvalid xs
|
||||
then let ys = complete xs
|
||||
in if countChunks ys == 8
|
||||
then IPv6NoPort ys
|
||||
else IPInvalid
|
||||
else IPInvalid
|
||||
IPv4WithPort (IPv4Chunk a) p -> if portIsValid p
|
||||
then IPv4WithPort (IPv4Chunk a) p
|
||||
else IPInvalid
|
||||
IPv4NoPort (IPv4Chunk a) -> IPv4NoPort (IPv4Chunk a)
|
||||
_ -> IPInvalid
|
||||
|
||||
zeroChunk = IPv6Chunk "0000"
|
||||
|
||||
portIsValid a = all isDigit a && between 0 65535 (read a)
|
||||
|
||||
complete xs = case break isIPZeroSection xs of
|
||||
(_, [IPZeroSection]) -> []
|
||||
(ys, []) -> ys
|
||||
([], (IPZeroSection:IPZeroSection:ys)) -> if any isIPZeroSection ys || countChunks ys > 7
|
||||
then []
|
||||
else replicate (8 - countChunks ys) zeroChunk ++ ys
|
||||
(ys, (IPZeroSection:zs)) -> if any isIPZeroSection zs || countChunks ys + countChunks zs > 7
|
||||
then []
|
||||
else ys ++ replicate (8 - countChunks ys - countChunks zs) zeroChunk ++ zs
|
||||
_ -> []
|
||||
|
||||
countChunks xs = foldl f 0 xs
|
||||
where f n (IPv4Chunk _) = n + 2
|
||||
f n (IPv6Chunk _) = n + 1
|
||||
|
||||
ip = parse2 . parse1
|
||||
|
||||
main = mapM_ (putStrLn . show . ip)
|
||||
["127.0.0.1", -- loop back
|
||||
"127.0.0.1:80", -- loop back +port
|
||||
"::1", -- loop back
|
||||
"[::1]:80", -- loop back +port
|
||||
"2605:2700:0:3::4713:93e3", -- Rosetta Code
|
||||
"[2605:2700:0:3::4713:93e3]:80"] -- Rosetta Code
|
||||
87
Task/Parse-an-IP-Address/VBScript/parse-an-ip-address.vb
Normal file
87
Task/Parse-an-IP-Address/VBScript/parse-an-ip-address.vb
Normal file
|
|
@ -0,0 +1,87 @@
|
|||
Function parse_ip(addr)
|
||||
'ipv4 pattern
|
||||
Set ipv4_pattern = New RegExp
|
||||
ipv4_pattern.Global = True
|
||||
ipv4_pattern.Pattern = "(\d{1,3}\.){3}\d{1,3}"
|
||||
'ipv6 pattern
|
||||
Set ipv6_pattern = New RegExp
|
||||
ipv6_pattern.Global = True
|
||||
ipv6_pattern.Pattern = "([0-9a-fA-F]{0,4}:){2}[0-9a-fA-F]{0,4}"
|
||||
'test if address is ipv4
|
||||
If ipv4_pattern.Test(addr) Then
|
||||
port = Split(addr,":")
|
||||
octet = Split(port(0),".")
|
||||
ipv4_hex = ""
|
||||
For i = 0 To UBound(octet)
|
||||
If octet(i) <= 255 And octet(i) >= 0 Then
|
||||
ipv4_hex = ipv4_hex & Right("0" & Hex(octet(i)),2)
|
||||
Else
|
||||
ipv4_hex = "Erroneous Address"
|
||||
Exit For
|
||||
End If
|
||||
Next
|
||||
parse_ip = "Test Case: " & addr & vbCrLf &_
|
||||
"Address: " & ipv4_hex & vbCrLf
|
||||
If UBound(port) = 1 Then
|
||||
If port(1) <= 65535 And port(1) >= 0 Then
|
||||
parse_ip = parse_ip & "Port: " & port(1) & vbCrLf
|
||||
Else
|
||||
parse_ip = parse_ip & "Port: Invalid" & vbCrLf
|
||||
End If
|
||||
End If
|
||||
End If
|
||||
'test if address is ipv6
|
||||
If ipv6_pattern.Test(addr) Then
|
||||
parse_ip = "Test Case: " & addr & vbCrLf
|
||||
port_v6 = "Port: "
|
||||
ipv6_hex = ""
|
||||
'check and extract port information if any
|
||||
If InStr(1,addr,"[") Then
|
||||
'extract the port
|
||||
port_v6 = port_v6 & Mid(addr,InStrRev(addr,"]")+2,Len(addr)-Len(Mid(addr,1,InStrRev(addr,"]")+1)))
|
||||
'extract the address
|
||||
addr = Mid(addr,InStrRev(addr,"[")+1,InStrRev(addr,"]")-(InStrRev(addr,"[")+1))
|
||||
End If
|
||||
word = Split(addr,":")
|
||||
word_count = 0
|
||||
For i = 0 To UBound(word)
|
||||
If word(i) = "" Then
|
||||
If i < UBound(word) Then
|
||||
If Int((7-(i+1))/2) = 1 Then
|
||||
k = 1
|
||||
ElseIf UBound(word) < 6 Then
|
||||
k = Int((7-(i+1))/2)
|
||||
ElseIf UBound(word) >= 6 Then
|
||||
k = Int((7-(i+1))/2)-1
|
||||
End If
|
||||
For j = 0 To k
|
||||
ipv6_hex = ipv6_hex & "0000"
|
||||
word_count = word_count + 1
|
||||
Next
|
||||
Else
|
||||
For j = 0 To (7-word_count)
|
||||
ipv6_hex = ipv6_hex & "0000"
|
||||
Next
|
||||
End If
|
||||
Else
|
||||
ipv6_hex = ipv6_hex & Right("0000" & word(i),4)
|
||||
word_count = word_count + 1
|
||||
End If
|
||||
Next
|
||||
parse_ip = parse_ip & "Address: " & ipv6_hex &_
|
||||
vbCrLf & port_v6 & vbCrLf
|
||||
End If
|
||||
'test if the address in invalid
|
||||
If ipv4_pattern.Test(addr) = False And ipv6_pattern.Test(addr) = False Then
|
||||
parse_ip = "Test Case: " & addr & vbCrLf &_
|
||||
"Address: Invalid Address" & vbCrLf
|
||||
End If
|
||||
End Function
|
||||
|
||||
'Testing the function
|
||||
ip_arr = Array("127.0.0.1","127.0.0.1:80","::1",_
|
||||
"[::1]:80","2605:2700:0:3::4713:93e3","[2605:2700:0:3::4713:93e3]:80","RosettaCode")
|
||||
|
||||
For n = 0 To UBound(ip_arr)
|
||||
WScript.StdOut.Write parse_ip(ip_arr(n)) & vbCrLf
|
||||
Next
|
||||
Loading…
Add table
Add a link
Reference in a new issue