Advertisement
Guest User

Untitled

a guest
Apr 23rd, 2017
57
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 1.73 KB | None | 0 0
  1. import Data.Char (chr, ord, toUpper)
  2.  
  3.  
  4. -- A bit of self documentation help
  5. type Key = String
  6. type Msg = String
  7.  
  8.  
  9. key :: Key
  10. key = "TSTING"
  11. msg :: Msg
  12. msg = "I'm not even mad... This is impressive!"
  13.  
  14.  
  15. -- | Checks if character is valid for encoding
  16. isValid :: Char -> Bool
  17. isValid c = let cUp = toUpper c :: Char
  18. in 'A' <= cUp && cUp <= 'Z'
  19.  
  20.  
  21. -- | Given 'key' & 'msg' generate a list of [Maybe Int] indices
  22. -- to map 'msg' from 'key', skipping invalid characters
  23. toIdx :: Key -> Msg -> [Maybe Int]
  24. toIdx k m = map (flip mod keyN <$>) $ toIdx_ 0 m
  25. where keyN = length k :: Int
  26. toIdx_ :: Int -> Msg -> [Maybe Int]
  27. toIdx_ _ "" = []
  28. toIdx_ acc (c:cs)
  29. | isValid c = Just acc : toIdx_ (acc + 1) cs
  30. | otherwise = Nothing : toIdx_ acc cs
  31.  
  32.  
  33. -- | Given 'key' & 'msg' generate a list of numbers representing
  34. -- the amount to shift 'msg' characters based on 'key'
  35. toShifts :: Key -> Msg -> [Int]
  36. toShifts k m = map toKey (toIdx k m)
  37. where kUp = map toUpper k :: Key
  38. toKey :: Maybe Int -> Int
  39. toKey Nothing = 0
  40. toKey (Just x) = ord (kUp!!x) - ord 'A'
  41.  
  42.  
  43. -- | Given 'by' & 'c', shift the Char 'c' by amount 'by'. 'by' can be both
  44. -- positive & negative as well as 0.
  45. shift :: Int -> Char -> Char
  46. shift by c
  47. | isValid c && c >= 'a' = shift_ $ ord 'a'
  48. | isValid c && c >= 'A' = shift_ $ ord 'A'
  49. | otherwise = c
  50. where cONorm = ord (toUpper c) - ord 'A' :: Int
  51. azN = ord 'Z' - ord 'A' :: Int
  52. shift_ :: Int -> Char
  53. shift_ aO = chr $ aO + mod (by + cONorm) azN
  54.  
  55.  
  56. -- Encode & decode a message using the given key.
  57. vigenere, unVigenere :: Key -> Msg -> Msg
  58. vigenere k m = zipWith shift (toShifts k m) m
  59. unVigenere k m = zipWith shift (map negate $ toShifts k m) m
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement