对于项目euler 59,我提出这个来返回一个包含decyphered字符串和使用的密钥的元组列表(是的,我知道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”是否合理?
答案 0 :(得分:2)
decyph key
将解密的文本作为[Char]
返回。使用语法
n <- decyph k
在列表理解中,n
将为Char
类型并分配已解密文本的各个字符,但您在此处想要的是为其分配{{1的完整结果这样做吧
decyph
最后,检查let n = decyph k
的类型:
elem
类型> :t elem
elem :: (Eq a) => a -> [a] -> Bool
为n
,第一个参数必须为[Char]
,但您有另一个字符串。如果您希望使用Char
,则可以将解密后的文本拆分为单词:
elems
这将在此编译。
PS:假设是合理的 文本将包含字符串“the”?
这肯定是一个常见的英文单词,但文字可能全部为大写,或"the" `elem` words n
可能只在句子的开头显示为the
。