0

对于 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”是否合理?

4

1 回答 1

2

decyph key将解密后的文本返回为[Char]. 随着语法

n <- decyph k

在您的列表理解中,n将是类型Char并被分配解密文本的各个字符,但您在这里想要的是它被分配完整的decyph结果

let n = decyph k

最后,检查类型elem

> :t elem
elem :: (Eq a) => a -> [a] -> Bool

对于nbeing的类型[Char],第一个参数必须是Char,但是那里还有另一个字符串。如果您希望使用elems,您可以将破译的文本拆分为单词:

"the" `elem` words n

这将在此处编译。

PS:假设文本将包含字符串“the”是否合理?

它肯定是一个常见的英语单词,但文本可能全大写,也the可能只出现The在句子的开头。

于 2009-12-19T13:55:13.547 回答