diff --git a/src/cipher_analytical_machine/analyzers/simple_substitution.clj b/src/cipher_analytical_machine/analyzers/simple_substitution.clj index 717b49b..802887b 100644 --- a/src/cipher_analytical_machine/analyzers/simple_substitution.clj +++ b/src/cipher_analytical_machine/analyzers/simple_substitution.clj @@ -1,8 +1,10 @@ (ns cipher-analytical-machine.analyzers.simple-substitution (:require [clojure.string :as cs] [clojure.math.combinatorics :as comb] + [cipher-analytical-machine.symbols.frequencies :as frequencies] [cipher-analytical-machine.ciphers.simple-substitution :as ss] [cipher-analytical-machine.analyzers.analyzers :as analyzers] + [cipher-analytical-machine.analyzers.analyzers :as ca] [cipher-analytical-machine.analyzers.caesar :as caesar]) (:gen-class)) @@ -42,3 +44,35 @@ (->> (map get-all-permutation-for-block possible-key-vector) (get-all-combinations-for-blocks))) +(defn get-possible-keys + "Return keys for a cipher text. A key is a map {\\a \\e, ...} to decrypt a text." + [cipher-text frequency-table] + (let [freq-symbol-str (frequencies/map-to-string frequency-table) ; "etaoinsrhldcumfpgwybvkxjqz" + char-map (-> (analyzers/count-characters cipher-text) + (analyzers/reverse-count-characters))] + (map (fn [comb] (zipmap comb freq-symbol-str)) + (-> (get-possible-key-vector-from-reversed-count-map char-map) + (get-possible-key-combinations))))) + + +(defn get-plain-data + "Return the plain data (score, text, key) from a ciphertext (a string of character). The function is case-insensitive." + [cipher-text letter-frequencies] + (let [cipher-text (cs/lower-case cipher-text) + keys (get-possible-keys cipher-text letter-frequencies)] + (->> (map (fn [key] [(ss/decrypt-message-by-symbol-table key cipher-text) key]) keys) + (map (fn [[text key]] [(ca/chi-squared-statistic text letter-frequencies) text key])) + ))) + +(defn get-plaintext-and-key + "Return the possible plaintext from a ciphertext that encoded with numbers. The function is case-insensitive." + [cipher-text letter-frequencies] + (let [maybe-key (->> (frequencies/map-to-string letter-frequencies) + (ss/generate-sorted-substitution-table)) + cipher-text (->> (cs/split cipher-text #",") + (map #(Integer/parseInt %)) + (ss/decrypt-message-by-symbol-table maybe-key))] + + (->> (get-plain-data cipher-text letter-frequencies) + (map (fn [el] (drop 1 el)) )))) +