# -*- coding: utf-8 -*- # http://projecteuler.net/problem=59 # # XOR暗号をブルーフォースアタックする. # 問題より,鍵は小文字(a-z)3文字なので,a-zから3つ選んだ順列で総当りする. # 問題より,鍵が正解した場合は,"よく用いられる英単語"が含まれるので, # ここでは " the " が含まれていれば正解とする. # "the"ではなく," the "にするのは,テキストの長さと最大繰り返し回数より, # "the"(3文字)ではランダムに発生する確率が高く,false positiveが起こるためである. WORD = " the " # ファイルを数値の配列として読み込み enc = File.read("cipher1.txt").split(/[\s,]+/).map(&:to_i) # a-zの3文字で総当り ('a' .. 'z').to_a.join('').unpack('C*').permutation(3).each do |key| # XORで復号 dec_text = enc.each_with_index.map{|c, i| c ^ key[i % 3] }.pack('C*') # WORDが含まれていれば正解 if (dec_text.include?(WORD)) puts dec_text.unpack("C*").reduce(:+) break end end