Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
5a4b88bd08 | ||
|
|
79ae13aa5a | ||
|
|
126a706292 | ||
|
|
178c85b0cb |
+2
-1
@@ -6,7 +6,8 @@
|
|||||||
:dependencies [[org.clojure/clojure "1.11.1"]
|
:dependencies [[org.clojure/clojure "1.11.1"]
|
||||||
[org.clojure/tools.cli "1.0.219"]
|
[org.clojure/tools.cli "1.0.219"]
|
||||||
[org.apache.tika/tika-core "1.28.5"]
|
[org.apache.tika/tika-core "1.28.5"]
|
||||||
[org.apache.tika/tika-langdetect "1.28.5"]]
|
[org.apache.tika/tika-langdetect "1.28.5"]
|
||||||
|
[cheshire "5.12.0"]]
|
||||||
:main ^:skip-aot cipher-analytical-machine.core
|
:main ^:skip-aot cipher-analytical-machine.core
|
||||||
:java-source-paths ["src/main/java"]
|
:java-source-paths ["src/main/java"]
|
||||||
:target-path "target/%s"
|
:target-path "target/%s"
|
||||||
|
|||||||
@@ -0,0 +1,63 @@
|
|||||||
|
(ns cipher-analytical-machine.ciphers.simple-substitution
|
||||||
|
(:require [clojure.string :as cs]
|
||||||
|
[cipher-analytical-machine.ciphers.caesar :as caesar])
|
||||||
|
(:gen-class))
|
||||||
|
|
||||||
|
(defn shuffled-numbers
|
||||||
|
"Generate the shuffled order for integer list."
|
||||||
|
[size]
|
||||||
|
(-> size
|
||||||
|
(take (range))
|
||||||
|
(shuffle)))
|
||||||
|
|
||||||
|
(defn generate-substitution-table
|
||||||
|
"Generate the map (char, int) for the substittion."
|
||||||
|
[symbols]
|
||||||
|
(->> (count symbols)
|
||||||
|
(shuffled-numbers)
|
||||||
|
(zipmap symbols)))
|
||||||
|
|
||||||
|
(defn generate-sorted-substitution-table
|
||||||
|
"Generate the map (char, int) for the substittion. BUT a value is the index of a symbol (from 0)."
|
||||||
|
[symbols]
|
||||||
|
(-> (count symbols)
|
||||||
|
(take (range))
|
||||||
|
(zipmap symbols)))
|
||||||
|
|
||||||
|
(defn find-value-in-table
|
||||||
|
"It uses the substitution table to find the value of a char or a number."
|
||||||
|
[char substitution-table]
|
||||||
|
(get substitution-table char))
|
||||||
|
|
||||||
|
(defn encrypt-message
|
||||||
|
"Encrypt a message using the simple substitution cipher. The function is case-insensitive. If a symbol isn't in the symbols list, then it will be removed."
|
||||||
|
[message substitution-table]
|
||||||
|
(->> message
|
||||||
|
(map (fn [char] (find-value-in-table char substitution-table)))
|
||||||
|
(remove nil?)
|
||||||
|
(cs/join \,)))
|
||||||
|
|
||||||
|
(defn encrypt-message-with-caesar
|
||||||
|
"Encrypt a message using the simple substitution cipher and the Caesar cipher. The function is case-insensitive. If a symbol isn't in the symbols list, then it will be removed."
|
||||||
|
[message key substitution-table symbols]
|
||||||
|
(-> message
|
||||||
|
(caesar/encrypt-message key symbols)
|
||||||
|
(encrypt-message substitution-table)))
|
||||||
|
|
||||||
|
(defn decrypt-message
|
||||||
|
"Decrypt a message using the simple substitution cipher. The function is case-insensitive. The substitution-table must be "
|
||||||
|
[message substitution-table]
|
||||||
|
(let [message (cs/split message #",")]
|
||||||
|
(->> message
|
||||||
|
(map #(Integer/parseInt %))
|
||||||
|
(map (fn [char] (find-value-in-table char substitution-table)))
|
||||||
|
(remove nil?)
|
||||||
|
(cs/join))))
|
||||||
|
|
||||||
|
(defn decrypt-message-with-caesar
|
||||||
|
"Decrypt a message using the simple substitution cipher and the Caesar cipher. The function is case-insensitive."
|
||||||
|
[message key substitution-table symbols]
|
||||||
|
(-> message
|
||||||
|
(decrypt-message substitution-table)
|
||||||
|
(caesar/decrypt-message key symbols)))
|
||||||
|
|
||||||
@@ -0,0 +1,9 @@
|
|||||||
|
(ns cipher-analytical-machine.parsers.parsers
|
||||||
|
(:require [cheshire.core :as cc])
|
||||||
|
(:gen-class))
|
||||||
|
|
||||||
|
(defn unsigned-int?
|
||||||
|
[str]
|
||||||
|
(if (re-matches #"\d+" str)
|
||||||
|
true false))
|
||||||
|
|
||||||
@@ -0,0 +1,44 @@
|
|||||||
|
(ns cipher-analytical-machine.parsers.simple-substitution
|
||||||
|
(:require
|
||||||
|
[cipher-analytical-machine.ciphers.simple-substitution :as ss]
|
||||||
|
[cipher-analytical-machine.parsers.parsers :as ps]
|
||||||
|
[cheshire.core :as cc])
|
||||||
|
(:gen-class))
|
||||||
|
|
||||||
|
(defn encode-key-and-substitution-table-to-json
|
||||||
|
[key substitution-table]
|
||||||
|
(-> {"key" key}
|
||||||
|
(assoc "table" substitution-table)
|
||||||
|
(cc/generate-string)))
|
||||||
|
|
||||||
|
(defn decode-key
|
||||||
|
"Returns the first character if the string is a char. Return the number if the string is a number."
|
||||||
|
[str]
|
||||||
|
(if (ps/unsigned-int? str)
|
||||||
|
(Integer/parseInt str)
|
||||||
|
(first str)))
|
||||||
|
|
||||||
|
(defn decode-pair
|
||||||
|
"Decode a numbers as a string and a char as a string"
|
||||||
|
[acc [key value]]
|
||||||
|
(if (ps/unsigned-int? key)
|
||||||
|
(assoc acc (decode-key key) (decode-key value))
|
||||||
|
(assoc acc (decode-key key) value)))
|
||||||
|
|
||||||
|
(defn decode-substitution-table
|
||||||
|
[substitution-table-map-from-json]
|
||||||
|
(reduce decode-pair {} substitution-table-map-from-json))
|
||||||
|
|
||||||
|
(defn decode-key-and-substitution-table-from-json
|
||||||
|
[json]
|
||||||
|
(let [data (cc/parse-string json)]
|
||||||
|
(assoc data "table" (decode-substitution-table (get data "table")))))
|
||||||
|
|
||||||
|
(defn generate-table-or-decode-json
|
||||||
|
"It generate the table and return map with the key and the table if the argument is a key. Else it decode the json."
|
||||||
|
[key-or-json symbols]
|
||||||
|
(if (ps/unsigned-int? key-or-json)
|
||||||
|
(-> {"key" key-or-json}
|
||||||
|
(assoc "table" (ss/generate-substitution-table symbols)))
|
||||||
|
(decode-key-and-substitution-table-from-json key-or-json)))
|
||||||
|
|
||||||
@@ -0,0 +1,68 @@
|
|||||||
|
(ns cipher-analytical-machine.ciphers.simple-substitution-test
|
||||||
|
(:require
|
||||||
|
[clojure.test :refer :all]
|
||||||
|
[cipher-analytical-machine.ciphers.simple-substitution :refer :all]))
|
||||||
|
|
||||||
|
(deftest find-value-in-table-test
|
||||||
|
(let [table {\a 1 \b 2 \c 3}
|
||||||
|
rtable {1 \a 2 \b 3 \c}]
|
||||||
|
(testing "If the symbol is in the table as a key, then the result won't nil."
|
||||||
|
(are [key expected]
|
||||||
|
(= expected (find-value-in-table key table))
|
||||||
|
\a 1
|
||||||
|
\d nil
|
||||||
|
1 nil
|
||||||
|
5 nil))
|
||||||
|
|
||||||
|
(testing "If the digit is in the reversed table as a key, then the result won't nil."
|
||||||
|
(are [key expected]
|
||||||
|
(= expected (find-value-in-table key rtable))
|
||||||
|
\a nil
|
||||||
|
\d nil
|
||||||
|
1 \a
|
||||||
|
5 nil))))
|
||||||
|
|
||||||
|
(deftest generate-sorted-substitution-table-test
|
||||||
|
(testing "If the symbol is in the table as a key, then the result won't nil."
|
||||||
|
(are [symbols expected-table]
|
||||||
|
(= expected-table (generate-sorted-substitution-table symbols))
|
||||||
|
"abc" {0 \a 1 \b 2 \c}
|
||||||
|
"a" {0 \a})))
|
||||||
|
|
||||||
|
(deftest encrypt-message-test
|
||||||
|
(let [symbols "abc"
|
||||||
|
table {\a 1 \b 2 \c 3}]
|
||||||
|
(testing "The function must encrypt the message and remove unknown symbols."
|
||||||
|
(are [message expected]
|
||||||
|
(= expected (encrypt-message message table))
|
||||||
|
"abc" "1,2,3"
|
||||||
|
"aDbdc" "1,2,3"))))
|
||||||
|
|
||||||
|
(deftest encrypt-message-with-caesar-test
|
||||||
|
(let [symbols "abc"
|
||||||
|
table {\a 1 \b 2 \c 3}]
|
||||||
|
(testing "The function must encrypt the message and remove unknown symbols."
|
||||||
|
(are [message key expected]
|
||||||
|
(= expected (encrypt-message-with-caesar message key table symbols))
|
||||||
|
"abc" 0 "1,2,3"
|
||||||
|
"abc" 1 "2,3,1"
|
||||||
|
"aDbdc" 0 "1,2,3"))))
|
||||||
|
|
||||||
|
(deftest decrypt-message-test
|
||||||
|
(let [table {1 \a 2 \b 3 \c}]
|
||||||
|
(testing "The function must decrypt the message and remove unknown numbers."
|
||||||
|
(are [message expected]
|
||||||
|
(= expected (decrypt-message message table))
|
||||||
|
"1,2,3" "abc"
|
||||||
|
"1,12,2,3" "abc"))))
|
||||||
|
|
||||||
|
(deftest decrypt-message-with-caesar-test
|
||||||
|
(let [symbols "abc"
|
||||||
|
table {1 \a 2 \b 3 \c}]
|
||||||
|
(testing "The function must decrypt the message and remove unknown numbers."
|
||||||
|
(are [message key expected]
|
||||||
|
(= expected (decrypt-message-with-caesar message key table symbols))
|
||||||
|
"1,2,3" 0 "abc"
|
||||||
|
"2,3,1" 1 "abc"
|
||||||
|
"1,12,2,3" 0 "abc"))))
|
||||||
|
|
||||||
@@ -0,0 +1,15 @@
|
|||||||
|
(ns cipher-analytical-machine.parsers.parsers-test
|
||||||
|
(:require
|
||||||
|
[clojure.test :refer :all]
|
||||||
|
[cipher-analytical-machine.parsers.parsers :refer :all]))
|
||||||
|
|
||||||
|
(deftest unsigned-int?-test
|
||||||
|
(testing ""
|
||||||
|
(are [str expected]
|
||||||
|
(= expected
|
||||||
|
(unsigned-int? str))
|
||||||
|
"9" true
|
||||||
|
"10" true
|
||||||
|
"-10" false
|
||||||
|
"abc" false)))
|
||||||
|
|
||||||
@@ -0,0 +1,41 @@
|
|||||||
|
(ns cipher-analytical-machine.parsers.simple-substitution-test
|
||||||
|
(:require
|
||||||
|
[clojure.test :refer :all]
|
||||||
|
[cipher-analytical-machine.parsers.simple-substitution :refer :all]))
|
||||||
|
|
||||||
|
(deftest encode-key-and-substitution-table-to-json-test
|
||||||
|
(testing "The encoder must parse the map and create a json."
|
||||||
|
(are [key table expected-json]
|
||||||
|
(= expected-json
|
||||||
|
(encode-key-and-substitution-table-to-json key table))
|
||||||
|
1 {0 \a 1 \b 2 \c} "{\"key\":1,\"table\":{\"0\":\"a\",\"1\":\"b\",\"2\":\"c\"}}"
|
||||||
|
2 {\a 0 \b 1 \c 2} "{\"key\":2,\"table\":{\"a\":0,\"b\":1,\"c\":2}}")))
|
||||||
|
|
||||||
|
(deftest decode-key-and-substitution-table-from-json-test
|
||||||
|
(testing "The decoder must parse the json and create a map."
|
||||||
|
(are [json expected-data]
|
||||||
|
(= expected-data
|
||||||
|
(decode-key-and-substitution-table-from-json json))
|
||||||
|
"{\"key\":1, \"table\":{\"0\":\"a\",\"1\":\"b\",\"2\":\"c\"}}" {"key" 1 "table" {0 \a 1 \b 2 \c}}
|
||||||
|
"{\"key\":2, \"table\":{\"a\":0,\"b\":1,\"c\":2}}" {"key" 2 "table" {\a 0 \b 1 \c 2}})))
|
||||||
|
|
||||||
|
(deftest generate-table-or-decode-json-test
|
||||||
|
(let [symbols "abc"]
|
||||||
|
(testing "The function decodes the json."
|
||||||
|
(are [json expected-data]
|
||||||
|
(= expected-data
|
||||||
|
(generate-table-or-decode-json json symbols))
|
||||||
|
"{\"key\":1, \"table\":{\"0\":\"a\",\"1\":\"b\",\"2\":\"c\"}}" {"key" 1 "table" {0 \a 1 \b 2 \c}}
|
||||||
|
"{\"key\":2, \"table\":{\"a\":0,\"b\":1,\"c\":2}}" {"key" 2 "table" {\a 0 \b 1 \c 2}}))
|
||||||
|
|
||||||
|
(testing "The function generates the table, because the argument is a key."
|
||||||
|
(are [json expected-data]
|
||||||
|
(let [data (generate-table-or-decode-json json symbols)]
|
||||||
|
(and (= (get expected-data "key")
|
||||||
|
(get data "key"))
|
||||||
|
(= (keys (get expected-data "table"))
|
||||||
|
(keys (get data "table"))))
|
||||||
|
(generate-table-or-decode-json json symbols))
|
||||||
|
"1" {"key" 1 "table" {0 \a 1 \b 2 \c}}
|
||||||
|
"2" {"key" 2 "table" {\a 0 \b 1 \c 2}}))))
|
||||||
|
|
||||||
Reference in New Issue
Block a user