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}