在Haskell中使用vigenere密码编码文本时遇到问题
我正在进行一个编码项目,我们需要在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
--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关于平行列表理解的链接,谢谢我学到了一些新东西:)