Compare commits

..
2 Commits
Author SHA1 Message Date
KKlochko 476a24c900 Fix the typo "frequences" to frequencies. 2023-10-12 22:00:01 +03:00
KKlochko 4d7e9da1d1 Refactor the project structure.
continuous-integration/drone/push Build is passing
2023-10-11 21:12:10 +03:00
15 changed files with 51 additions and 76 deletions
@@ -1,4 +1,4 @@
(ns cipher-analytical-machine.cipher-analyzers (ns cipher-analytical-machine.analyzers.analyzers
(:require [clojure.string :as cs]) (:require [clojure.string :as cs])
(:gen-class)) (:gen-class))
@@ -21,16 +21,16 @@
(defn chi-squared-statistic (defn chi-squared-statistic
"To calculate the frequency distribution of a language. More detail about the algorithm here: http://practicalcryptography.com/cryptanalysis/text-characterisation/chi-squared-statistic/" "To calculate the frequency distribution of a language. More detail about the algorithm here: http://practicalcryptography.com/cryptanalysis/text-characterisation/chi-squared-statistic/"
[text letter-frequences] [text letter-frequencies]
(let [length-text (count text) (let [length-text (count text)
letter-counts (count-characters (cs/lower-case text))] letter-counts (count-characters (cs/lower-case text))]
;letter-counts ;letter-counts
(reduce (reduce
(fn [acc [char count]] (fn [acc [char count]]
(+ acc (+ acc
(if (contains? letter-frequences char) (if (contains? letter-frequencies char)
(chi-squared-letter-statistic count (chi-squared-letter-statistic count
(get letter-frequences char) (get letter-frequencies char)
length-text) length-text)
0))) 0)))
0 0
@@ -1,9 +1,9 @@
(ns cipher-analytical-machine.caesar-analyzers (ns cipher-analytical-machine.analyzers.caesar
(:require [cipher-analytical-machine.caesar :as caesar] (:require [cipher-analytical-machine.ciphers.caesar :as caesar]
[clojure.string :as cs] [clojure.string :as cs]
[cipher-analytical-machine.cipher-analyzers :as ca]) [cipher-analytical-machine.analyzers.analyzers :as ca])
(:import [cipher_analytical_machine.ciphers.caesar Decrypted] (:import [cipher_analytical_machine.ciphers.caesar Decrypted]
[cipher_analytical_machine.analizers.caesar FrequencyAnalyzer]) [cipher_analytical_machine.analyzers.caesar FrequencyAnalyzer])
(:gen-class)) (:gen-class))
(defn get-all-texts (defn get-all-texts
@@ -17,9 +17,9 @@
(defn get-all-scores (defn get-all-scores
"For pairs (key, plaintext) finds scores and return list of pairs [key, score]." "For pairs (key, plaintext) finds scores and return list of pairs [key, score]."
[letter-frequences pairs] [letter-frequencies pairs]
(map (fn [[key text]] (map (fn [[key text]]
[key (ca/chi-squared-statistic text letter-frequences)]) [key (ca/chi-squared-statistic text letter-frequencies)])
pairs)) pairs))
(defn get-min-score-pair (defn get-min-score-pair
@@ -34,18 +34,18 @@
(defn get-key (defn get-key
"To find the key with frequencies of letters." "To find the key with frequencies of letters."
[ciphertext symbols letter-frequences] [ciphertext symbols letter-frequencies]
(->> (get-all-texts ciphertext symbols) (->> (get-all-texts ciphertext symbols)
(get-all-scores letter-frequences) (get-all-scores letter-frequencies)
(get-min-score-pair) (get-min-score-pair)
(first))) (first)))
(defn get-plaintext (defn get-plaintext
"Return the plaintext from a ciphertext. The function is case-insensitive." "Return the plaintext from a ciphertext. The function is case-insensitive."
[ciphertext symbols letter-frequences] [ciphertext symbols letter-frequencies]
(let [ciphertext (cs/lower-case ciphertext)] (let [ciphertext (cs/lower-case ciphertext)]
(caesar/decrypt-message ciphertext (caesar/decrypt-message ciphertext
(get-key ciphertext symbols letter-frequences) (get-key ciphertext symbols letter-frequencies)
symbols))) symbols)))
(defn frequency-analizer-get-plaintext (defn frequency-analizer-get-plaintext
@@ -1,4 +1,4 @@
(ns cipher-analytical-machine.language-analyzer (ns cipher-analytical-machine.analyzers.language
(:import [org.apache.tika.language LanguageIdentifier]) (:import [org.apache.tika.language LanguageIdentifier])
(:gen-class)) (:gen-class))
@@ -1,4 +1,4 @@
(ns cipher-analytical-machine.caesar (ns cipher-analytical-machine.ciphers.caesar
(:require [clojure.string :as cs]) (:require [clojure.string :as cs])
(:gen-class)) (:gen-class))
@@ -1,10 +1,10 @@
(ns cipher-analytical-machine.cli (ns cipher-analytical-machine.cli.cli
(:require (:require
[cipher-analytical-machine.file :as file] [cipher-analytical-machine.cli.file :as file]
[cipher-analytical-machine.caesar :as caesar] [cipher-analytical-machine.ciphers.caesar :as caesar]
[cipher-analytical-machine.caesar-analyzers :as caesar-analyzers] [cipher-analytical-machine.analyzers.caesar :as caesar-analyzers]
[cipher-analytical-machine.symbol-factories :as sf] [cipher-analytical-machine.symbols.factories :as sf]
[cipher-analytical-machine.symbol-frequences :as symbol-frequences] [cipher-analytical-machine.symbols.frequencies :as symbol-frequencies]
[clojure.string :as cs] [clojure.string :as cs]
[clojure.tools.cli :refer [parse-opts]]) [clojure.tools.cli :refer [parse-opts]])
(:gen-class)) (:gen-class))
@@ -155,7 +155,7 @@
[options arguments action-type] [options arguments action-type]
(let [message (:message options) (let [message (:message options)
symbols (:symbols options) symbols (:symbols options)
frequencies symbol-frequences/english-letter-frequences] frequencies symbol-frequencies/english-letter-frequencies]
(cond (cond
(= action-type :cracking) (= action-type :cracking)
(caesar-analyzers/get-plaintext message symbols frequencies) (caesar-analyzers/get-plaintext message symbols frequencies)
@@ -1,4 +1,4 @@
(ns cipher-analytical-machine.file (ns cipher-analytical-machine.cli.file
(:require [clojure.java.io :as io]) (:require [clojure.java.io :as io])
(:gen-class)) (:gen-class))
+1 -1
View File
@@ -1,6 +1,6 @@
(ns cipher-analytical-machine.core (ns cipher-analytical-machine.core
(:require (:require
[cipher-analytical-machine.cli :as cli]) [cipher-analytical-machine.cli.cli :as cli])
(:gen-class)) (:gen-class))
(defn -main (defn -main
@@ -1,4 +1,4 @@
(ns cipher-analytical-machine.symbol-factories (ns cipher-analytical-machine.symbols.factories
(:require [clojure.string :as cs]) (:require [clojure.string :as cs])
(:gen-class)) (:gen-class))
@@ -1,4 +1,4 @@
(ns cipher-analytical-machine.symbol-frequences (ns cipher-analytical-machine.symbols.frequencies
(:gen-class)) (:gen-class))
(def english-letter-frequences { (def english-letter-frequences {
@@ -1,4 +1,4 @@
package cipher_analytical_machine.analizers.caesar; package cipher_analytical_machine.analyzers.caesar;
import cipher_analytical_machine.ciphers.caesar.Decrypted; import cipher_analytical_machine.ciphers.caesar.Decrypted;
import java.util.Map; import java.util.Map;
@@ -1,9 +1,9 @@
(ns cipher-analytical-machine.caesar-analyzers-test (ns cipher-analytical-machine.analyzers.caesar-test
(:require (:require
[clojure.test :refer :all] [clojure.test :refer :all]
[cipher-analytical-machine.caesar-analyzers :refer :all] [cipher-analytical-machine.analyzers.caesar :refer :all]
[cipher-analytical-machine.symbol-frequences :as sf] [cipher-analytical-machine.symbols.frequencies :as sf]
[cipher-analytical-machine.cipher-analyzers :as ca] [cipher-analytical-machine.analyzers.analyzers :as ca]
[clojure.string :as cs])) [clojure.string :as cs]))
(deftest get-all-texts-test (deftest get-all-texts-test
@@ -25,9 +25,9 @@
(testing "There're 27 combinations for a 'Hello World'." (testing "There're 27 combinations for a 'Hello World'."
(let [ciphertext "khoorczruog" (let [ciphertext "khoorczruog"
symbols "abcdefghijklmnopqrstuvwxyz " symbols "abcdefghijklmnopqrstuvwxyz "
frequences sf/english-letter-frequences frequencies sf/english-letter-frequencies
text-pairs (get-all-texts ciphertext symbols)] text-pairs (get-all-texts ciphertext symbols)]
(is (= 27 (count (get-all-scores frequences text-pairs))))))) (is (= 27 (count (get-all-scores frequencies text-pairs)))))))
(deftest get-min-score-pair-test (deftest get-min-score-pair-test
(testing "If a key is one, then the min score pair is 15." (testing "If a key is one, then the min score pair is 15."
@@ -40,47 +40,47 @@
ciphertext "khoorczruog" ciphertext "khoorczruog"
key 3 key 3
symbols "abcdefghijklmnopqrstuvwxyz " symbols "abcdefghijklmnopqrstuvwxyz "
frequences sf/english-letter-frequences] frequencies sf/english-letter-frequencies]
(testing "The plaintext is encrypted with 3 as the key." (testing "The plaintext is encrypted with 3 as the key."
(is (= key (get-key ciphertext symbols frequences))))) (is (= key (get-key ciphertext symbols frequencies)))))
(let [; З поеми "Кавказ" Тараса Григоровича Шевченка: (let [; З поеми "Кавказ" Тараса Григоровича Шевченка:
plaintext "Борітеся – поборете, Вам Бог помагає! За вас правда, за вас слава. І воля святая!" plaintext "Борітеся – поборете, Вам Бог помагає! За вас правда, за вас слава. І воля святая!"
ciphertext "жхчощйшде–ецхжхчйщй,езєуежхиецхуєиєк!емєезєшецчєзїє,емєезєшештєзє.еоезхтдешздщєд!" ciphertext "жхчощйшде–ецхжхчйщй,езєуежхиецхуєиєк!емєезєшецчєзїє,емєезєшештєзє.еоезхтдешздщєд!"
key 7 key 7
symbols "абвгґдеєжзиіїйклмнопрстуфхцчшщьюя " symbols "абвгґдеєжзиіїйклмнопрстуфхцчшщьюя "
frequences sf/ukrainian-letter-frequences] frequencies sf/ukrainian-letter-frequencies]
(testing "The plaintext is encrypted with 3 as the key." (testing "The plaintext is encrypted with 3 as the key."
(is (= key (get-key ciphertext symbols frequences)))))) (is (= key (get-key ciphertext symbols frequencies))))))
(deftest get-plaintext-test (deftest get-plaintext-test
(let [plaintext "hello world" (let [plaintext "hello world"
ciphertext "khoorczruog" ciphertext "khoorczruog"
symbols "abcdefghijklmnopqrstuvwxyz " symbols "abcdefghijklmnopqrstuvwxyz "
frequences sf/english-letter-frequences] frequencies sf/english-letter-frequencies]
(testing "The plaintext is encrypted with 3 as the key." (testing "The plaintext is encrypted with 3 as the key."
(is (= plaintext (get-plaintext ciphertext symbols frequences)))) (is (= plaintext (get-plaintext ciphertext symbols frequencies))))
(testing "The ciphertext is case-insensitive." (testing "The ciphertext is case-insensitive."
(is (= plaintext (get-plaintext "KhoorcZruog" symbols frequences))))) (is (= plaintext (get-plaintext "KhoorcZruog" symbols frequencies)))))
(let [; З поеми "Кавказ" Тараса Григоровича Шевченка: (let [; З поеми "Кавказ" Тараса Григоровича Шевченка:
plaintext "Борітеся – поборете, Вам Бог помагає! За вас правда, за вас слава. І воля святая!" plaintext "Борітеся – поборете, Вам Бог помагає! За вас правда, за вас слава. І воля святая!"
ciphertext "жхчощйшде–ецхжхчйщй,езєуежхиецхуєиєк!емєезєшецчєзїє,емєезєшештєзє.еоезхтдешздщєд!" ciphertext "жхчощйшде–ецхжхчйщй,езєуежхиецхуєиєк!емєезєшецчєзїє,емєезєшештєзє.еоезхтдешздщєд!"
key 7 key 7
symbols "абвгґдеєжзиіїйклмнопрстуфхцчшщьюя " symbols "абвгґдеєжзиіїйклмнопрстуфхцчшщьюя "
frequences sf/ukrainian-letter-frequences] frequencies sf/ukrainian-letter-frequencies]
(testing "The ciphertext is case-insensitive." (testing "The ciphertext is case-insensitive."
(is (= (cs/lower-case plaintext) (is (= (cs/lower-case plaintext)
(get-plaintext ciphertext symbols frequences)))))) (get-plaintext ciphertext symbols frequencies))))))
(deftest frequency-analizer-get-plaintext-test (deftest frequency-analizer-get-plaintext-test
(let [plaintext "abc" (let [plaintext "abc"
ciphertext "bca" ciphertext "bca"
key 1 key 1
symbols "abc" symbols "abc"
frequences sf/english-letter-frequences] frequencies sf/english-letter-frequencies]
(testing "The ciphertext is 'bca' and key is 1." (testing "The ciphertext is 'bca' and key is 1."
(is (= plaintext (is (= plaintext
(frequency-analizer-get-plaintext ciphertext symbols frequences)))))) (frequency-analizer-get-plaintext ciphertext symbols frequencies))))))
@@ -1,7 +1,7 @@
(ns cipher-analytical-machine.language-analyzer-test (ns cipher-analytical-machine.analyzers.language-test
(:require (:require
[clojure.test :refer :all] [clojure.test :refer :all]
[cipher-analytical-machine.language-analyzer :refer :all] [cipher-analytical-machine.analyzers.language :refer :all]
)) ))
(deftest detect-language-test (deftest detect-language-test
@@ -1,25 +0,0 @@
(ns cipher-analytical-machine.cipher-analyzers-test
(:require
[clojure.test :refer :all]
[cipher-analytical-machine.cipher-analyzers :refer :all]))
(deftest count-characters-test
(testing "Count two dublicates and one uniq character from a string."
(is (= {\a 2 \b 1}
(count-characters "aba")))))
(deftest chi-squared-letter-statistic-test
(testing "If the frequence of A is 0.1, the text length is 100 and contains 20 times, then the chi-squared is 10."
(is (= 10.0
(chi-squared-letter-statistic 20 0.1 100))))
(testing "If the frequence of A is 0.1, the text length is 10 and contains 5 times, then the chi-squared is 16.0."
(is (= 16.0
(chi-squared-letter-statistic 5 0.1 10)))))
(deftest chi-squared-statistic-test
(let [text "aaaaabbbbb"]
(testing "If the frequences of a and b is 0.1, the text length is 10 and contains them 5 times, then score is 32."
(is (= 32.0
(chi-squared-statistic text {\a 0.1 \b 0.1}))))))
@@ -1,7 +1,7 @@
(ns cipher-analytical-machine.caesar-test (ns cipher-analytical-machine.ciphers.caesar-test
(:require (:require
[clojure.test :refer :all] [clojure.test :refer :all]
[cipher-analytical-machine.caesar :refer :all] [cipher-analytical-machine.ciphers.caesar :refer :all]
)) ))
(deftest calculate-char-index-test (deftest calculate-char-index-test
@@ -1,7 +1,7 @@
(ns cipher-analytical-machine.symbol-factories-test (ns cipher-analytical-machine.symbols.factories-test
(:require (:require
[clojure.test :refer :all] [clojure.test :refer :all]
[cipher-analytical-machine.symbol-factories :refer :all] [cipher-analytical-machine.symbols.factories :refer :all]
)) ))
(deftest english-alphabet-factory-test (deftest english-alphabet-factory-test