在Haskell中使用vigenere密码编码文本时遇到问题

在Haskell中使用vigenere密码编码文本时遇到问题,haskell,encryption,vigenere,Haskell,Encryption,Vigenere,我正在进行一个编码项目,我们需要在Haskell中编写一个vigenere密码。我花了几个小时,几乎没有取得什么进展,但我在一个特定的部分卡住了。以下是我目前的代码: --Program: VigCipher.hs --Author: Mouse import Data.Char import Text.Printf --Changes letters to their numerical value let2int :: Char -> Int let2int c = ord c

我正在进行一个编码项目,我们需要在Haskell中编写一个vigenere密码。我花了几个小时,几乎没有取得什么进展,但我在一个特定的部分卡住了。以下是我目前的代码:

--Program: VigCipher.hs
--Author: Mouse

import Data.Char
import Text.Printf

--Changes letters to their numerical value
let2int   :: Char -> Int
let2int c = ord c - ord 'a'

--Changes numerical values to letters
int2let   :: Int -> Char
int2let n = chr (ord 'a' + n)

--Shift letter by n mod 26 places
shift :: Int -> Char -> Char
shift n c | isLower c = int2let ((let2int c + n) `mod` 26)
      | otherwise = c

--Encoding function
encode         :: String -> String -> [Char]
encode key msg = [shift (26 - let2int (key !! a) | a <- as) (msg !! a) | x <- zip (cycle key)msg]
--程序:vigchipher.hs
--作者:鼠标
导入数据.Char
导入文本.Printf
--将字母更改为其数值
let2int::Char->Int
let2int c=ord c-ord“a”
--将数值更改为字母
int2let::Int->Char
int2let n=chr(ord'a'+n)
--将字母移位n模26位
shift::Int->Char->Char
移位n c |岛下c=int2let((let2int c+n)`mod`26)
|否则=c
--编码功能
encode::String->String->[Char]
encode key msg=[shift(26-let2int(key!!a)| a语法为

[element | bindings, guards]
你的语法错误是

  • 有两个
    |
    符号
  • 第一个
    |
    出现在元素部分完成之前(计算括号)
所以试试看

encode key msg = [shift (26 - let2int (key !! a)) (msg !! a)
                 | a <- as, x <- zip (cycle key) msg]
你说你很困惑,因为你收到了一条错误消息,表明你没有给出它所需要的三个参数

您已经给了
一个参数,它是
(fst()key msg)

我设想您将代码更改为,类似于

encode key msg = zipWith f (cycle key) msg
  where f keyElem msgElem = shift (26 - let2int keyElem) msgElem
语法是

[element | bindings, guards]
你的语法错误是

  • 有两个
    |
    符号
  • 第一个
    |
    出现在元素部分完成之前(计算括号)
所以试试看

encode key msg = [shift (26 - let2int (key !! a)) (msg !! a)
                 | a <- as, x <- zip (cycle key) msg]
你说你很困惑,因为你收到了一条错误消息,表明你没有给出它所需要的三个参数

您已经给了
一个参数,它是
(fst()key msg)

我设想您将代码更改为,类似于

encode key msg = zipWith f (cycle key) msg
  where f keyElem msgElem = shift (26 - let2int keyElem) msgElem
启用后(通过在文件顶部粘贴
{-#LANGUAGE parallellelistcomp#-}
,或在GHCi中输入
:set-XParallelListComp
),您可以编写:

encode key msg = [shift (26 - let2int k) m | k <- cycle key | m <- msg]
i、 dave4420的解决方案。他的解决方案更加惯用,不依赖于GHC扩展——所以一定要使用它!我想我会展示一种简洁的编写方法。

启用(通过粘贴
{-#LANGUAGE parallelistcomp}
在文件顶部,或通过在GHCi中输入
:set-XParallelListComp
),您可以编写:

encode key msg = [shift (26 - let2int k) m | k <- cycle key | m <- msg]

i、 e.dave4420的解决方案。他的解决方案更加惯用,不依赖于GHC扩展,所以请务必使用它!我想我会展示一种简洁的写作方式。

如果您包含错误,可能会有所帮助如果您包含错误,可能会有所帮助如果我想让它遍历消息的每个索引d更改它,我是否应该更改长度(msg)?否,因为
as
必须是一个列表。因此,将其替换为
[0..length msg-1]
。但请注意,使用
!!
通常是一个坏主意(链接列表不是数组):您可以根据
zipWith
重写
shift
表达式,并完全删除
a
变量。重写是指重写shift方法还是重写我在编码方法中使用shift的地方?对不起,我以前的措辞很糟糕。我的意思是重写
encode
,以便它使用
zipWith
shift
而不是使用列表理解和
shift
。好的,我已经编辑了使用zipWith的代码,但是现在它给了我错误,因为它认为我使用的参数太少。这就是我得到的:encode key msg=[shift(26-let2int(x))(msg)| x所以如果我想让它遍历消息的每个索引并更改它,我是否应该更改长度(msg)?否,因为
as
必须是一个列表。所以用
[0..length msg-1]
替换它。但是请注意,使用
!!
通常是个坏主意(链接列表不是数组):您可以根据
zipWith
重写
shift
表达式,并完全删除
a
变量。重写是指重写shift方法还是重写我在编码方法中使用shift的地方?对不起,我以前的措辞很糟糕。我的意思是重写
encode
,以便它使用
zipWith
shift
而不是使用列表理解和
shift
。好的,我已经编辑了使用zipWith的代码,但是现在它给了我错误,因为它认为我使用的参数太少。这就是我得到的:encode key msg=[shift(26-let2int(x))(msg)| x+1关于平行列表理解的链接,谢谢我学到了一些新东西:)+1关于平行列表理解的链接,谢谢我学到了一些新东西:)