|
|
@ -1,8 +1,10 @@
|
|
|
|
(ns cipher-analytical-machine.analyzers.simple-substitution
|
|
|
|
(ns cipher-analytical-machine.analyzers.simple-substitution
|
|
|
|
(:require [clojure.string :as cs]
|
|
|
|
(:require [clojure.string :as cs]
|
|
|
|
[clojure.math.combinatorics :as comb]
|
|
|
|
[clojure.math.combinatorics :as comb]
|
|
|
|
|
|
|
|
[cipher-analytical-machine.symbols.frequencies :as frequencies]
|
|
|
|
[cipher-analytical-machine.ciphers.simple-substitution :as ss]
|
|
|
|
[cipher-analytical-machine.ciphers.simple-substitution :as ss]
|
|
|
|
[cipher-analytical-machine.analyzers.analyzers :as analyzers]
|
|
|
|
[cipher-analytical-machine.analyzers.analyzers :as analyzers]
|
|
|
|
|
|
|
|
[cipher-analytical-machine.analyzers.analyzers :as ca]
|
|
|
|
[cipher-analytical-machine.analyzers.caesar :as caesar])
|
|
|
|
[cipher-analytical-machine.analyzers.caesar :as caesar])
|
|
|
|
(:gen-class))
|
|
|
|
(:gen-class))
|
|
|
|
|
|
|
|
|
|
|
@ -42,3 +44,35 @@
|
|
|
|
(->> (map get-all-permutation-for-block possible-key-vector)
|
|
|
|
(->> (map get-all-permutation-for-block possible-key-vector)
|
|
|
|
(get-all-combinations-for-blocks)))
|
|
|
|
(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)) ))))
|
|
|
|
|
|
|
|
|
|
|
|