module Vigenere where import Data.Char type StringHash = String type StringMess = String type CharHash = Char type CharMess = Char type CharHashCounter = Int toVigy :: StringHash -> StringMess -> StringMess toVigy "" mess = mess toVigy _ "" = "" toVigy unfilteredHash mess = let hash = filter isAlpha unfilteredHash in goShiftify 0 hash mess fromVigy :: StringHash -> StringMess -> StringMess fromVigy "" mess = mess fromVigy _ "" = "" fromVigy unfilteredHash mess = let hash = filter isAlpha unfilteredHash in goUnshiftify 0 hash mess goShiftify :: CharHashCounter -> StringHash -> StringMess -> StringMess goShiftify count hash "" = "" goShiftify count hash (x:xs) = let isChar = isAlpha x nextCount = count + fromEnum isChar hashChar = charHashPicker count hash in (if isChar then shiftify hashChar x else x):(goShiftify nextCount hash xs) charHashPicker :: CharHashCounter -> StringHash -> CharHash charHashPicker count hash = hash !! (mod count (length hash)) shiftify :: CharHash -> CharMess -> Char shiftify h m = chr . (+base) . (flip mod 25) . (shiftBy + ) . (subtract base) . fromEnum $ m where base = if (isUpper m) then 65 else 97 shiftBy = getShiftBy h unshiftify :: CharHash -> CharMess -> Char unshiftify h m = chr . (+base) . (flip mod 25) . (subtract shiftBy ) . (subtract base) . fromEnum $ m where base = if (isUpper m) then 65 else 97 shiftBy = getShiftBy h goUnshiftify :: CharHashCounter -> StringHash -> StringMess -> StringMess goUnshiftify count hash "" = "" goUnshiftify count hash (x:xs) = let isChar = isAlpha x nextCount = count + fromEnum isChar hashChar = charHashPicker count hash in (if isChar then unshiftify hashChar x else x):(goUnshiftify nextCount hash xs) getShiftBy :: Char -> Int getShiftBy x = fromEnum x - (if isUpper x then 65 else 97)