«Цезарь просто заменил каждую букву в сообщении на букву в трех местах дальше по алфавиту, заключив ее в конец алфавита». Мы можем просто написать это на Хаскеле.Фактически мы можем избежать let2num
и num2let
в целом.
Итак, давайте начнем с определения таблицы для сопоставления простого текстового алфавита с алфавитом зашифрованного текста:
cipher = let abc = ['a'..'z']
code = drop 3 abc ++ take 3 abc
in zip abc code
Это будет выглядетькак
[('a','d'),('b','e'),('c','f'),('d','g'), ... ]
Теперь мы можем зашифровать символ, если просто lookup
буква в этом словаре:
ghci> lookup 'a' cipher
Just 'd'
lookup
возвращает значение Maybe Char
, нам нужночтобы преобразовать его просто в Char
, и для этого я использую функцию maybe
, используя '?'
для символов, которые не были найдены в шифре, и id
(функция идентификации = без изменений) для найденных символов:
ghci> maybe '?' id (lookup 'a' cipher)
'd'
Теперь мы можем написать функцию encrypt
для кодирования только одного символа, оставляя пропущенные символы, например пробел, незашифрованными:
encrypt c = maybe c id (lookup c cipher)
Для шифрования всей строки:
ghci> map encrypt "haskell is fun"
"kdvnhoo lv ixq"
Итак, мы можем собрать все вместе:
encrypt c = maybe c id (lookup c cipher)
where
cipher = let abc = ['a'..'z']
code = drop 3 abc ++ take 3 abc
in zip abc code