Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
378 views
in Technique[技术] by (71.8m points)

haskell - Vigenere Cipher not encoding properly

calcAlphaPos :: Char -> Int
calcAlphaPos a 
    | (a `elem` ['a'..'z']) = ord(a) - ord('a')
    | (a `elem` ['A'..'Z']) = ord(a) - ord('A') 
    | otherwise = 0

calcOffset :: String -> Int -> Int
calcOffset word pos = calcAlphaPos (word !! (pos `mod` (length word)))
          
encodex :: Int -> Char -> Char
encodex offset ch
    | (ch `elem` ['a'..'z']) = chr ((((ord ch - ord ('a')) + offset + 26) `mod` 26) + ord('a'))
    | (ch `elem` ['A'..'Z']) = chr ((((ord ch - ord ('A')) + offset + 26) `mod` 26) + ord('A'))
    | otherwise = ch

encode :: String -> String -> Int -> String
encode _ [] _ = "...End of message"
encode [] _ _ = "Invalid decoder word!"
encode word (x:xs) y
    | (word !! wordpos) `elem` ['a'..'z'] = [encodex (calcOffset word y) x] ++ encode word xs (y+1)
    | (word !! wordpos) `elem` ['A'..'Z'] = [encodex (calcOffset word y) x] ++ encode word xs (y+1)
    | otherwise = [x] ++ encode word xs y
     where wordpos = y `mod` length word
   
  1. encode "ALLY" "MEET AT DAWN" 0

    should produce MPPR AE OYWY but produces MPPR LE DLHL
    
    note "ALLY" provides offset of 0, 11, 11, 24
    MEET =                 [12,  4,  4, 19]
    MPPR =                 [12, 15, 15, 17] <-- 43 - 26 = 17
    

I'm learning haskell and have been trying to figure out what I am doing wrong in regards to the Vegenere cipher. When I don't use spaces in the message the cipher works but I can't seem to figure out how to get it to work when spaces are included.

question from:https://stackoverflow.com/questions/65910708/vigenere-cipher-not-encoding-properly

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

This is embarassing but what I did wrong is that I checked each letter in the key to see if it had a special character rather than checking each character in the message. I replaced encode with this:

encode :: String -> String -> Int -> String
encode _ [] _ = "...End of message"
encode [] _ _ = "Invalid decoder word!"
encode word (x:xs) y
    | x `elem` ['a'..'z'] = [encodex (calcOffset word y) x] ++ encode word xs (y+1)
    | x `elem` ['A'..'Z'] = [encodex (calcOffset word y) x] ++ encode word xs (y+1)
    | otherwise = [x] ++ encode word xs y
    where wordpos = y `mod` length word

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...