package ixee.cryptopals.solvers import ixee.cryptopals.utils._ import ixee.cryptopals.utils.ByteUtils._ object XorDecrypt { implicit val freq = Frequencies.cornell40kSample def tryBestDecrypt(ciphertext: Seq[Byte]) = { val key = findBestSingleByteKey(ciphertext) new String((ciphertext xor Stream.continually(key)).toArray) } def findBestSingleByteKey(ciphertext: Seq[Byte]): Byte = candidates(ciphertext) .minBy(_._1)._2.toByte def candidates(ciphertext: Seq[Byte]) = (0 until 256) .map(_.toByte) .map(x => TextScorer.score(ciphertext xor Stream.continually(x))) .zipWithIndex .filter(_._1 != -1.0) def candidatesAsAscii(ciphertext: Seq[Byte]) = candidates(ciphertext).sortBy(_._1).map(x => new String((ciphertext xor Stream.continually(x._2.toByte)).toArray) ) }