I wrote a little program to do generalized caesar ciphers. I can’t figure out why my brute force function for decrypting isn’t working. All I’m trying to do is try every possible combination of multiplier and offset less than 26. Also, if anyone can suggest a better approach for the “tryallcombinations” function, that would be appreciated.
import Data.Char
caesarencipher::Int->Int->String->String
caesarencipher r s p = map chr $ map encipher plaintext
where
plaintext = map (\x->(ord x) - 97) p
encipher p = (mod (r*p + s) 26) + 97
caesardecipher::Int->Int->String->String
caesardecipher r s c = map chr $ map decipher ciphertext
where
ciphertext = map (\x->(ord x) - 97) c
inverser x | mod (r * x) 26 == 1 = x
| otherwise = inverser (x + 1)
decipher c = (mod ((inverser 1) * (c - s)) 26) + 97
tryallcombinations::String->[String]
tryallcombinations ciphertext = map (\x->x ciphertext) possibilities
where
rs = map caesardecipher [0..25]
possibilities = concat $ map (\x-> map x [0..25]) rs
26 is not a prime, so not all numbers have a modular inverse mod 26. That means that inverser sometimes never returns but recurses forever.