(ns cipher-analytical-machine.analyzers.caesar (:require [cipher-analytical-machine.ciphers.caesar :as caesar] [clojure.string :as cs] [cipher-analytical-machine.analyzers.language :as language] [cipher-analytical-machine.analyzers.analyzers :as ca]) (:import [cipher_analytical_machine.ciphers.caesar Decrypted] [cipher_analytical_machine.analyzers.caesar IsNonsense] [cipher_analytical_machine.analyzers.caesar FrequencyAnalyzer]) (:gen-class)) (defn get-all-texts "Return a list of pairs which have a key and a second posible plaintext." [ciphertext symbols] (let [keys (range (count symbols))] (reduce (fn [acc key] (conj acc [key (caesar/decrypt-message ciphertext key symbols)])) '() keys))) (defn get-all-scores "For pairs (key, plaintext) finds scores and return list of pairs [key, score]." [letter-frequencies pairs] (map (fn [[key text]] [key (ca/chi-squared-statistic text letter-frequencies)]) pairs)) (defn get-min-score-pair "For pairs (key, plaintext) finds scores and return list of pairs [key, score]." [pairs] (reduce (fn [[key value] [new-key new-value]] (if (> value new-value) [new-key new-value] [key value])) [0 Double/MAX_VALUE] pairs)) (defn get-key "To find the key with frequencies of letters." [ciphertext symbols letter-frequencies] (->> (get-all-texts ciphertext symbols) (get-all-scores letter-frequencies) (get-min-score-pair) (first))) (defn get-plaintext "Return the plaintext from a ciphertext. The function is case-insensitive." [ciphertext symbols letter-frequencies] (let [ciphertext (cs/lower-case ciphertext)] (caesar/decrypt-message ciphertext (get-key ciphertext symbols letter-frequencies) symbols))) (defn frequency-analizer-get-plaintext "Return the plaintext from a ciphertext using simple analizer. The function is case-insensitive." [ciphertext symbols letter-frequencies-string language-code] (let [decrypt (reify Decrypted (decrypt [this message key symbols] (caesar/decrypt-message message key symbols))) is-nonsense (reify IsNonsense (isNonsense [this message] (language/is-nonsense? message language-code)))] (-> (new FrequencyAnalyzer ciphertext symbols letter-frequencies-string decrypt is-nonsense) .crack)))