module Lib ( createAlphabetFromText, encryptCaesar, decryptCaesar, textToBits, bitsToText ) where import Data.Char (ord, chr) import Data.Bits (testBit) import qualified Data.Vector.Unboxed as VU createAlphabetFromText :: String -> [Char] createAlphabetFromText [] = [] createAlphabetFromText (x:xs) | x `elem` alphabet = alphabet | otherwise = x : alphabet where alphabet = createAlphabetFromText xs indexOf :: (Eq t) => [t] -> t -> Int indexOf [] _ = -1 indexOf (x : xs) target | x == target = 0 | otherwise = 1 + indexOf xs target encryptCaesar :: [Char] -> Int -> String -> String encryptCaesar alphabet shift text = map caesarChar text where caesarChar c = alphabet !! ((indexOf alphabet c + shift) `mod` length alphabet) decryptCaesar :: [Char] -> Int -> String -> String decryptCaesar alphabet shift = encryptCaesar alphabet (alphabetLength - (shift `mod` alphabetLength)) where alphabetLength = length alphabet textToBits :: String -> VU.Vector Int textToBits text = VU.fromList $ concatMap charToBits text where charToBits c = [if testBit (ord c) i then 1 else 0 | i <- [7,6..0]] bitsToText :: VU.Vector Int -> String bitsToText bits | VU.null bits = [] | otherwise = (chr $ bitsToInt (VU.take 8 bits)) : bitsToText (VU.drop 8 bits) where bitsToInt charBits = sum [bit * (2 ^ index) | (bit, index) <- zip (VU.toList charBits) [7 :: Int,6..0]]