Для проекта euler 59 я придумал это, чтобы получить список кортежей, содержащих дешифрованную строку и используемый ключ (и да, я знаю о Data.Bits
):
module XOR where
import Data.List
import Data.Char
decToBin :: Integer -> [Integer]
decToBin x = reverse $ decToBin' x
where
decToBin' 0 = []
decToBin' y = let (a,b) = quotRem y 2 in [b] ++ decToBin' a
binToDec :: [Integer] -> Integer
binToDec xs = foldl (+) 0 $ map (\(x,y) -> x*(2^y) ) $reverse $ zip (reverse xs) [0..]
bitwise f x y = zipWith f x y
lenBin :: Integer -> Integer
lenBin x= length$ decToBin x
xor :: Integer -> Integer -> Bool
xor x y | x == y = 0
| x /= y = 1
| otherwise = error "Impossible"
bitwiseXOR :: Integer -> Integer -> Integer
bitwiseXOR a b | (lenBin a) > (lenBin b) = binToDec $ bitwise xor ((replicate ((lenBin a) - (lenBin b)) 0)++(decToBin b)) (decToBin a)
| (lenBin a) < (lenBin b) = binToDec $ bitwise xor ((replicate ((lenBin b) - (lenBin a)) 0)++(decToBin a)) (decToBin b)
| otherwise =binToDec $ bitwise xor (decToBin b) (decToBin a)
decyph :: [char] -> [char]
decyph key = map chr $ map (\(x,y)-> bitwiseXOR x (ord y) ) $ zip numbers $ cycle key
brute :: [([Char],[Char])]
brute = [(n,k)|k<- (sequence $ replicate 3 ['a'..'z']) ,n <- decyph k, "the" `isInfixOf` n]
numbers :: [Integer]
numbers = [79,59,12,2,79,35,8...]
Проблема в том, что когда я не могу запустить decyph
, потому что создаваемые им кортежи содержат только один символ в первой части и ключ во второй, а не весь расшифрованный текст с использованным ключом. Как я могу это исправить?
PS: Разумно ли предположить, что текст будет содержать строку "the"?