(ns cipher-analytical-machine.analyzers.simple-substitution (:require [clojure.string :as cs] [clojure.math.combinatorics :as comb] [cipher-analytical-machine.ciphers.simple-substitution :as ss] [cipher-analytical-machine.analyzers.analyzers :as analyzers] [cipher-analytical-machine.analyzers.caesar :as caesar]) (:gen-class)) (defn get-possible-key-vector "Convert a possible key map to a vector of possible keys. For example, if you have a map: {\\a [\\a \\b \\c] \\b [\\b \\c] \\c [\\a \\c]}, then the vector is [[\\a \\b \\c] [\\b \\c] [\\a \\c]]." [possible-key-map symbols] (reduce (fn [acc el] (conj acc (get possible-key-map el))) [] symbols)) (defn get-possible-key-vector-from-reversed-count-map "Convert a reversed count map to a vector. Example, from {2 [\\a \\b] 1 [\\d] 3 [\\e]} to [[\\e] [\\a \\b] [\\d]])." [reversed-count-map] (->> reversed-count-map (into []) (sort-by #(- (first %))) (map second) (into []))) (defn get-all-permutation-for-block "Return a vector for all possible blocks that can be made from a vector of symbols." [symbols] (->> (comb/permutations symbols) (map cs/join) (into []))) (defn get-all-combinations-for-blocks "Return the all combination of blocks in a possible key vector. For example, if you have a map: {\\a [\\a \"bf\" \\c] \\b [\"bf\" \\c] \\c [\\a \\c]}, then the vector is [[\\a \"bf\" \\c] [\"bf\" \\c] [\\a \\c]] and keys (\"abfa\" \"abfc\" ...)." [possible-key-vector] (->> (apply comb/cartesian-product possible-key-vector) (map cs/join)))