language: Haskell (ghc-6.8.2)
date: 124 days 8 hours ago
link:
visibility: public
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
module Main where
 
import Control.Applicative
import Control.Monad
import Data.Bits
import Data.Char
import Data.Word
import Data.Function
import Text.ParserCombinators.ReadP
 
-- * Byte fucking
   
type IP32Address = Word32
 
getOctet :: Int -> IP32Address -> Word8
getOctet n a = fromIntegral $ a `shiftR` (n * 8) .&. 255
 
setOctet :: Int -> Word8 -> IP32Address -> IP32Address 
setOctet n x a = a .&. mask .|. (fromIntegral x `shiftL` offset)
    where offset = n * 8
          mask   = complement $ 255 `shiftL` offset
 
-- * Parser          
          
readDigit :: ReadP Int
readDigit = digitToInt <$> satisfy isDigit
 
upTo1 :: Int -> ReadP a -> ReadP [a]
upTo1 0 _ = return []
upTo1 n p = upTo1' (fix (\f -> \n -> upTo1' f n <++ return [] ) ) n 
    where upTo1' _ 0 = return []
          upTo1' f n = liftM2 (:) p $ f (n - 1)
 
readIntUpTo :: Int -> ReadP Int
readIntUpTo n = foldl op 0 <$> upTo1 n readDigit
    where op f d = f * 10 + fromIntegral d 
 
readOctet :: ReadP Word8
readOctet = do
    a <- readIntUpTo 3 
    if a > 255 
        then pfail 
        else return $ fromIntegral a
    
readIp :: ReadP IP32Address
readIp = do
    a <- setOctet' 3 0 <$> readOctet
    foldM (\a n -> char '.' >> setOctet' n a <$> readOctet) a [2,1,0]
    where setOctet' = flip . setOctet
    
parseIP :: String -> Maybe IP32Address
parseIP s = case readP_to_S readIp s of
                []  -> Nothing
                a:_ -> Just $ fst a
    
-- * Printer
 
showIP :: IP32Address -> String
showIP a = foldl (\s n -> shows (getOctet n a) ('.':s)) (show $ getOctet 0 a) [1..3]
    
-- * Main
 
main = do
    putStrLn "Enter teh first IP address:"
    a <- ensure =<< parseIP <$> getLine
    putStrLn "Enter teh second IP address:"
    b <- ensure =<< parseIP <$> getLine
    putStrLn $ "Address range (exclusive) from " ++ showIP a ++ " to " ++ showIP b ++ " (including network and broadcast addresses):"
    if (a /= maxBound) && (succ a < b) 
        then printAddresses (succ a) b
        else putStrLn "[none]"
    where 
        ensure s = case s of
                    Just a  -> return a
                    Nothing -> fail "nable to parse IP address"
                        
        printAddresses a b = do
            putStrLn $ showIP a
            if (succ a < b)
                then printAddresses (succ a) b
                else return ()
  • upload with new input
  • result: Runtime error     time: 0.01s    memory: 3624 kB     signal: -1

    Enter teh first IP address:
    
    prog: <stdin>: hGetLine: end of file