Bacon cipher: Difference between revisions
Content added Content deleted
(→{{header|Haskell}}: Applied hlint, hindent, inlined comments, added main.) |
|||
Line 938: | Line 938: | ||
=={{header|Haskell}}== |
=={{header|Haskell}}== |
||
Necessary imports |
<lang haskell>-- Necessary imports |
||
import Data.List (elemIndex, unfoldr) |
|||
import Data. |
import Data.Bool (bool) |
||
import Data. |
import Data.Char (isAlpha, isUpper, toLower, toUpper) |
||
import Data.List.Split (chunksOf) |
|||
The list of characters to be encoded: |
-- The list of characters to be encoded: |
||
chars :: String |
|||
chars = ['a' .. 'z'] ++ ['0' .. '9'] ++ ",.;?! " |
|||
⚫ | |||
⚫ | |||
⚫ | |||
bitsPerChar = 6 |
|||
⚫ | |||
⚫ | |||
⚫ | |||
⚫ | |||
⚫ | |||
fromBinary :: [Bool] -> Int |
fromBinary :: [Bool] -> Int |
||
fromBinary = foldr (\x n -> 2*n + bool 0 1 x) 0 |
fromBinary = foldr (\x n -> (2 * n) + bool 0 1 x) 0 |
||
And |
-- And finally, main functions -- encoding: |
||
encode :: String -> String -> Either String String |
|||
encode |
encode txt message = do |
||
mask <- traverse coding message |
mask <- traverse coding message |
||
zipAlphas (bool toLower toUpper) (concat mask) txt |
zipAlphas (bool toLower toUpper) (concat mask) txt |
||
where |
where |
||
coding ch = |
coding ch = |
||
case elemIndex ch chars of |
|||
Nothing -> Left $ "Unknown symbol " ++ show ch |
|||
Nothing -> Left $ "Unknown symbol " ++ show ch |
|||
Just i -> Right $ take bitsPerChar (toBinary i) |
|||
zipAlphas f = go |
zipAlphas f = go |
||
where |
where |
||
go _ [] = Left "Text is not long enough!" |
|||
go [] _ = Right [] |
|||
go (x:xs) (y:ys) |
|||
| isAlpha y = (f x y :) <$> go xs ys |
|||
| otherwise = (y :) <$> go (x : xs) ys |
|||
And decoding: |
-- And decoding: |
||
decode :: String -> String |
|||
decode = map decipher . chunksOf bitsPerChar . filter isAlpha |
decode = map decipher . chunksOf bitsPerChar . filter isAlpha |
||
where |
where |
||
decipher = (chars !!) . min (length chars-1) . fromBinary . map isUpper |
decipher = (chars !!) . min (length chars - 1) . fromBinary . map isUpper |
||
chunksOf n = takeWhile (not . null) . unfoldr (pure . splitAt n) |
chunksOf n = takeWhile (not . null) . unfoldr (pure . splitAt n) |
||
⚫ | |||
text :: String |
|||
text = |
|||
unwords |
|||
⚫ | |||
⚫ | |||
⚫ | |||
⚫ | |||
⚫ | |||
⚫ | |||
⚫ | |||
] |
|||
message :: String |
|||
⚫ | |||
main :: IO () |
|||
main = do |
|||
⚫ | |||
mapM_ |
|||
(either |
|||
(putStrLn . ("-> " ++)) |
|||
(putStrLn . (++ "\n") . unlines . fmap unwords . chunksOf 10 . words)) |
|||
[ m |
|||
⚫ | |||
⚫ | |||
, encode "abc" message |
|||
]</lang> |
|||
{{Out}} |
|||
<pre>BAcoN's CIPher is A metHod Of StegaNogrApHy creAted By franCiS |
|||
baCon. ThIS task iS to iMplEMEnt a PRoGrAm FOr eNcrYpTIoN |
|||
and dECRypTIOn Of PlaInTExt Using ThE simPLe aLPHAbet Of tHe |
|||
BacOnIaN CIphEr Or Some OtheR kinD oF rePrESEntAtION of thiS |
|||
alpHabEt (MAKe Anything sIgnIFy anyTHiNg). tHe BAConian ALPhabET may |
|||
⚫ | |||
⚫ | |||
⚫ | |||
⚫ | |||
⚫ | |||
⚫ | |||
⚫ | |||
⚫ | |||
⚫ | |||
⚫ | |||
⚫ | |||
⚫ | |||
⚫ | |||
λ> m |
|||
Right "BAcoN's CIPher is A metHod Of StegaNogrApHy creAted By franCiS baCon. ThIS task iS to iMplEMEnt a PRoGrAm FOr eNcrYpTIoN and dECRypTIOn Of PlaInTExt Using ThE simPLe aLPHAbet Of tHe BacOnIaN CIphEr Or Some OtheR kinD oF rePrESEntAtION of thiS alpHabEt (MAKe Anything sIgnIFy anyTHiNg). tHe BAConian ALPhabET may" |
|||
⚫ | |||
⚫ | |||
⚫ | |||
⚫ | |||
λ> encode message "abc" |
|||
⚫ | |||
=={{header|J}}== |
=={{header|J}}== |