unkr/lib.rs
1//! # Unkr decrypt and bruteforce old school cyphers
2//!
3//! - Encrypt and Decrypt strings using old school cryptography, like Vigenere, Transposition, and more.
4//! - Bruteforce challenges when knowing a part of the clear text.
5//! - Print out all possible strings and look for words inside yourself.
6//!
7//! ## Decrypt/Encrypt Examples
8//!
9//! ### Basic
10//! ```bash
11//! $ echo "ABCDEF" | unkr encrypt -- transpose:2
12//! ACE
13//! BDF
14//! ```
15//!
16//! ### Kryptos panel K1
17//!
18//! ```bash
19//! $ echo "EMUFPHZLRFAXYUSDJKZLDKRNSHGNFIVJYQTQUXQBQVYUVLLTREVJYQTMKYRDMFD" | unkr decrypt -- vigenere:PALIMPSEST:KRYPTOS
20//! BETWEENSUBTLESHADINGANDTHEABSENCEOFLIGHTLIESTHENUANCEOFIQLUSION
21//! ```
22//!
23//! ### Kryptos panel k2
24//!
25//! (passing string as argument instead of stdin)
26//!
27//! ```bash
28//! $ unkr decrypt --string 'VFPJUDEEHZWETZYVGWHKKQETGFQJNCEGGWHKK?DQMCPFQZDQMMIAGPFXHQRLGTIMVMZJANQLVKQEDAGDVFRPJUNGEUNAQZGZLECGYUXUEENJTBJLBQCRTBJDFHRRYIZETKZEMVDUFKSJHKFWHKUWQLSZFTIHHDDDUVH?DWKBFUFPWNTDFIYCUQZEREEVLDKFEZMOQQJLTTUGSYQPFEUNLAVIDXFLGGTEZ?FKZBSFDQVGOGIPUFXHHDRKFFHQNTGPUAECNUVPDJMQCLQUMUNEDFQELZZVRRGKFFVOEEXBDMVPNFQXEZLGREDNQFMPNZGLFLPMRJQYALMGNUVPDXVKPDQUMEBEDMHDAFMJGZNUPLGEWJLLAETG' -- 'vigenere:ABSCISSA:KRYPTOS'
29//! ITWASTOTALLYINVISIBLEHOWSTHATPOSSIBLE?THEYUSEDTHEEARTHSMAGNETICFIELDXTHEINFORMATIONWASGATHEREDANDTRANSMITTEDUNDERGRUUNDTOANUNKNOWNLOCATIONXDOESLANGLEYKNOWABOUTTHIS?THEYSHOULDITSBURIEDOUTTHERESOMEWHEREXWHOKNOWSTHEEXACTLOCATION?ONLYWWTHISWASHISLASTMESSAGEXTHIRTYEIGHTDEGREESFIFTYSEVENMINUTESSIXPOINTFIVESECONDSNORTHSEVENTYSEVENDEGREESEIGHTMINUTESFORTYFOURSECONDSWESTIDBYROWS
30//! ```
31//!
32//! ### Kryptos panel k3
33//!
34//! There is some confusion here between encrypt and decrypt, I need to fix the right verb but I am not sure about what to for `transpose` actually.
35//!
36//! Also symbols are totally ignored.
37//!
38//!```bash
39//! $ cargo run -- encrypt --string "ENDYAHROHNLSRHEOCPTEOIBIDYSHNAIACHTNREYULDSLLSLLNOHSNOSMRWXMNETPRNGATIHNRARPESLNNELEBLPIIACAEWMTWNDITEENRAHCTENEUDRETNHAEOETFOLSEDTIWENHAEIOYTEYQHEENCTAYCREIFTBRSPAMHHEWENATAMATEGYEERLBTEEFOASFIOTUETUAEOTOARMAEERTNRTIBSEDDNIAAHTTMSTEWPIEROAGRIEWFEBAECTDDHILCEIHSITEGOEAOSDDRYDLORITRKLMLEHAGTDHARDPNEOHMGFMFEUHEECDMRIPFEIMEHNLSSTTRTVDOHW?" -- transpose:24 reverse transpose:8 reverse join
40//! SLOWLYDESPARATLYSLOWLYTHEREMAINSOFPASSAGEDEBRISTHATENCUMBEREDTHELOWERPARTOFTHEDOORWAYWASREMOVEDWITHTREMBLINGHANDSIMADEATINYBREACHINTHEUPPERLEFTHANDCORNERANDTHENWIDENINGTHEHOLEALITTLEIINSERTEDTHECANDLEANDPEEREDINTHEHOTAIRESCAPINGFROMTHECHAMBERCAUSEDTHEFLAMETOFLICKERBUTPRESENTLYDETAILSOFTHEROOMWITHINEMERGEDFROMTHEMISTXCANYOUSEEANYTHINGQ
41//!```
42//!
43//! ### ASD Coin
44//!
45//! see https://www.asd.gov.au/news-events-speeches/events/2022-09-01-75th-anniversary-commemorative-coin
46//!
47//!```bash
48//! $ echo "URMWXOZIRGBRM7DRWGSC5WVKGS" | cargo run -- encrypt -- atbash
49//!
50//! FINDCLARITYIN7WIDTHX5DEPTH
51//!
52//! $ echo "DVZIVZFWZXRLFHRMXLMXVKGZMWNVGRXFOLFHRMVCVXFGRLM" | cargo run -- encrypt -- atbash
53//!
54//! WEAREAUDACIOUSINCONCEPTANDMETICULOUSINEXECUTION
55//!
56//! $ echo "BGOAMVOEIATSIRLNGTTNEOGRERGXNTEAIFC" | cargo run -- encrypt -- cut:35 transpose:7 join
57//!
58//! BELONGINGTOAGREATTEAMSTRIVINGFOREXC
59//!
60//! $ echo "ECAIEOALEKFNR5LWEFCHDEEAEEE7NMDRXX5" | cargo run -- encrypt -- cut:35 transpose:7 join
61//!
62//! ELLENCEWEMAKEADIFFERENCEXORHEXA5D75
63//! ```
64//!
65//!
66//! ## Cryptors
67//!
68//! Current cryptors are
69//! ```
70//! # use unkr::models::{BruteForceCryptor, NumberArgs, PermuteArgs,BruteForceVigenereArgs,BruteForcePermuteArgs};
71//! # let cryptors = unkr::get_decryptors();
72//! assert_eq!(cryptors, vec![
73//! BruteForceCryptor::Vigenere(BruteForceVigenereArgs { // [...]
74//! # alphabet_depth: 1,
75//! # key_depth: 2,
76//! }),
77//! BruteForceCryptor::Cut,
78//! BruteForceCryptor::Caesar,
79//! BruteForceCryptor::Transpose,
80//! BruteForceCryptor::AtBash,
81//! BruteForceCryptor::Reverse,
82//! BruteForceCryptor::Swap,
83//! BruteForceCryptor::Join,
84//! BruteForceCryptor::Permute(BruteForcePermuteArgs { // [...]
85//! # max_permutations: 2,
86//! }),
87//! ]);
88//! ```
89//!
90//! ## Bruteforce
91//!
92//! The second interesting feature is bruteforcing using clues.
93//!
94//! ```bash
95//! cargo run -- bruteforce --decryptors enigma --string ILBDARKFH --clues HELLOTEST --threads 16
96//!
97//! ```
98
99use cryptors::{
100 char_utils,
101 enigma::{self, EnigmaArgs},
102 permute, transpose,
103};
104use models::{BruteForceCryptor, NumberArgs, PermuteArgs};
105mod base;
106mod brute_force;
107mod brute_force_state;
108mod cache;
109mod candidates;
110mod colorize;
111mod combinator;
112mod console;
113mod cryptors;
114mod decrypt;
115mod decryptors;
116mod encrypt;
117mod fuzzer;
118mod mapper;
119// pub for benchmark, but not sure that it is really required
120pub mod models;
121mod parser;
122mod thread_system;
123
124pub fn fuzz_next_string_ruled(
125 str: &String,
126 len_max: usize,
127 base: usize,
128 unique_letters_constraint: bool,
129 pair_length_constraint: bool,
130 sorted_by_pair_constraint: bool,
131) -> Option<String> {
132 fuzzer::fuzz_next_string_ruled(
133 str,
134 len_max,
135 base,
136 unique_letters_constraint,
137 pair_length_constraint,
138 sorted_by_pair_constraint,
139 )
140}
141
142pub fn print_encrypt(strs: Vec<String>, decryptors: Vec<String>) {
143 encrypt::print_encrypt(strs, decryptors)
144}
145
146pub fn print_decrypt(str: Vec<String>, decryptors: Vec<String>) {
147 decrypt::print_decrypt(str, decryptors)
148}
149
150pub fn brute_force_decrypt(
151 str: String,
152 clues: Vec<String>,
153 steps: u8,
154 decryptors: Vec<String>,
155 threads_numbers: Vec<u8>,
156 threads_count: u8,
157 pretty: bool,
158 cache_name: String,
159) {
160 brute_force::brute_force_decrypt(
161 str,
162 clues,
163 steps,
164 decryptors,
165 threads_numbers,
166 threads_count,
167 pretty,
168 cache_name,
169 )
170}
171
172/// Return current supported decryptors.
173pub fn get_decryptors() -> Vec<BruteForceCryptor> {
174 decryptors::get_decryptors()
175}
176
177pub fn brute_force_unique_combination(
178 str: String,
179 clues: Vec<String>,
180 decryptors: Vec<String>,
181 threads_number: Vec<u8>,
182 total_threads: u8,
183 cache_name: String,
184 pretty: bool,
185 intermediate_steps: bool,
186) {
187 brute_force::brute_force_unique_combination(
188 str,
189 clues,
190 decryptors,
191 threads_number,
192 total_threads,
193 cache_name,
194 pretty,
195 intermediate_steps,
196 )
197}
198
199pub fn print_combine_elements(elements_count: u8, picks: u8) {
200 combinator::print_combine_elements(elements_count, picks)
201}
202
203pub fn read_bruteforce_parameters(str: String) -> BruteForceCryptor {
204 parser::read_bruteforce_parameters(str)
205}
206
207pub fn fuzz_from(str: String, len_max: usize, base: usize, rules: Vec<String>) {
208 fuzzer::fuzz_from(str, len_max, base, rules)
209}
210
211pub fn fuzz_next(str: &Vec<u8>, len_max: usize, base: usize) -> Option<Vec<u8>> {
212 fuzzer::fuzz_next(str, len_max, base, &(base as u8 - 1))
213}
214
215pub fn enigma_next(enigma_args: EnigmaArgs) -> Option<EnigmaArgs> {
216 enigma::next(enigma_args)
217}
218
219pub fn enigma_init() -> EnigmaArgs {
220 enigma::init()
221}
222
223pub fn enigma_encrypt(strs: Vec<String>, enigma_args: EnigmaArgs) -> Vec<String> {
224 enigma::encrypt(strs, enigma_args)
225}
226
227pub fn transpose_init() -> NumberArgs {
228 transpose::init()
229}
230
231pub fn transpose_next(strs: Vec<String>, number_args: NumberArgs) -> Option<NumberArgs> {
232 transpose::next(strs, number_args)
233}
234
235pub fn transpose_decrypt(strs: Vec<String>, number_args: NumberArgs) -> Vec<String> {
236 transpose::decrypt(strs, number_args)
237}
238
239pub fn permute_init() -> PermuteArgs {
240 permute::init()
241}
242
243pub fn permute_next(
244 permute_brute_force_state: models::PermuteBruteForceState,
245) -> Option<models::PermuteArgs> {
246 permute::next(permute_brute_force_state)
247}
248
249pub fn permute_decrypt(strs: Vec<String>, permute_args: PermuteArgs) -> Vec<std::string::String> {
250 permute::decrypt(strs, permute_args)
251}
252
253pub fn char_position(c: char) -> usize {
254 char_utils::char_position_base(c)
255}