Skip to content

Instantly share code, notes, and snippets.

@Dennis960
Created December 6, 2023 23:16
Show Gist options
  • Save Dennis960/3ebccaa7944062816adaecf89bf88d2d to your computer and use it in GitHub Desktop.
Save Dennis960/3ebccaa7944062816adaecf89bf88d2d to your computer and use it in GitHub Desktop.
Haskell vigenereCipher
import Data.Char (chr, ord, toLower, isLetter)
-- | Vigenere Cipher
vigenereCipher2 :: String -> String -> String
vigenereCipher2 message key = zipWith (curry shiftCharByKey) message (prepareKey message key) where
-- | Prepares the key to skip foreign chars by setting the key to 'a' at these positions and repeats the key so it matches the messages length
prepareKey :: String -> String -> String
prepareKey [] _ = []
prepareKey (m:message) (k:key) = if isLetter m then k : prepareKey message (key ++ [k]) else 'a' : prepareKey message (k : key)
-- | Shifts a character depending on the position of the key's character in the alphabet
shiftCharByKey :: (Char, Char) -> Char
shiftCharByKey (m, k) = chr $ ord m + shiftAmount where
mIndex = ord (toLower m) - ord 'a'
kIndex = ord (toLower k) - ord 'a'
shiftAmount = if mIndex + kIndex < 26 then kIndex else kIndex - 26
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment