带有单词密钥的凯撒密码 Haskell

Caesar Cipher with a key of a word Haskell

我正在编写一个 caesar ciper,其中密钥作为一个词输入,该词的数值是移位因子(如果不够长,数字模式将重复)。我只将其应用于大写字母。我的加密函数或我的 shiftFactor 函数有问题,因为它将加密“ABC”ABC“输出为”ABCBCDCDE“而不仅仅是”ACE“。我是 haskell 的新手,所以当我通过逻辑进行追踪时我找不到明显的问题。

encrypt :: String -> String -> String
encrypt key xs = [shift sf x| x<-xs, sf<-shiftFactorArray]
    where shiftFactorArray = shiftFactor(key)

shiftFactor :: String -> [Int]
shiftFactor key = [let2int(x)|x<-key]

我也调用的函数由

定义
shift :: Int -> Char -> Char
shift n c | isUpper c = int2let ((let2int c + n) `mod` 26)
          | otherwise = c

let2int :: Char -> Int
let2int c = ord c - ord 'A'

int2let :: Int -> Char
int2let n = chr (ord 'A' + n)

通过使用 x <- xssf <- shiftFactorArray,您将遍历 ss 的每个元素和 shiftFactorArray 的每个元素。您需要在 parallel 中迭代两个列表的东西。您可以为此使用 zipWith :: (a -> b -> c) -> [a] -> [b] -> [c]

为了每次重复按键,可以使用cycle :: [a] -> [a]:

encrypt :: String -> String -> String
encrypt key xs = zipWith shift (cycle (shiftFactor key)) xs

shiftFactor :: String -> [Int]
shiftFactor = map let2int

然后我们得到:

Prelude Data.Char> encrypt "ABC" "ABCFOOBAR"
"ACEFPQBBT"

我们可以encryptpoint-free,利用函数组合:

encrypt :: String -> String -> String
encrypt = zipWith shift <b>. cycle . map let2int</b>