module Lib ( createAlphabetFromText, encryptCaesar, decryptCaesar, textToBits, bitsToText, encodePixel ) where import Codec.Picture import Data.Word (Word8) 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 charToBits :: Char -> [Int] 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) bitsToInt :: VU.Vector Int -> Int bitsToInt charBits = sum [bit * (2 ^ index) | (bit, index) <- zip (VU.toList charBits) [7 :: Int,6..0]] encodePixel :: Int -> Image PixelRGB8 -> VU.Vector Int -> Int -> Int -> PixelRGB8 encodePixel bitsPerByte img bits x y = PixelRGB8 newR newG newB where width = imageWidth img index = x + y * width startPos = index * 3 * bitsPerByte pixelBits = VU.slice startPos (3 * bitsPerByte) bits intToWord8 :: Int -> Word8 intToWord8 x = fromIntegral x bitsR = intToWord8 $ (VU.take bitsPerByte pixelBits) VU.! 0 bitsG = bitsToInt $ VU.take bitsPerByte $ VU.drop bitsPerByte pixelBits bitsB = bitsToInt $ VU.drop (2 * bitsPerByte) pixelBits PixelRGB8 r g b = pixelAt img x y newR = bitsR newG = intToWord8 bitsG newB = b