0

プロジェクトオイラー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生成されているタプルが、使用されているキーを含む復号化されたテキスト全体ではなく、最初の部分に1文字、2番目の部分にキーしか含まれていないために実行できないことです。どうすればこれを修正できますか?

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

タイプn[Char]、の場合、最初の引数はである必要がありますがChar、そこに別の文字列があります。で作業したい場合はelems、解読されたテキストを単語に分割することができます。

"the" `elem` words n

これはここでコンパイルされます。

PS:テキストに文字列「the」が含まれると想定するのは合理的ですか?

これは確かに一般的な英語の単語ですが、テキストはすべて大文字であるか、文の先頭にtheのみ表示される可能性があります。The

于 2009-12-19T13:55:13.547 に答える