summaryrefslogtreecommitdiff
path: root/src/solvers
diff options
context:
space:
mode:
authoriximeow <me@iximeow.net>2014-11-23 03:09:27 -0800
committeriximeow <me@iximeow.net>2014-11-23 03:09:27 -0800
commitaa390776b26d794ab37aa13833fa7043aad16504 (patch)
tree5535ab96683e2db3ddbcd31d33b223982d080d0c /src/solvers
parent5dcdf12a091f42b3f80b49b442f9885bcd786972 (diff)
Add in code for challenge 3
Diffstat (limited to 'src/solvers')
-rw-r--r--src/solvers/XorDecrypt.scala29
1 files changed, 29 insertions, 0 deletions
diff --git a/src/solvers/XorDecrypt.scala b/src/solvers/XorDecrypt.scala
new file mode 100644
index 0000000..b7f7c43
--- /dev/null
+++ b/src/solvers/XorDecrypt.scala
@@ -0,0 +1,29 @@
+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)
+ )
+}