From 08a2c5c1d817bbe1909c3e40412ff0e75e00ffa9 Mon Sep 17 00:00:00 2001 From: SkeletalDemise <29117662+SkeletalDemise@users.noreply.github.com> Date: Wed, 17 May 2023 04:54:52 -0700 Subject: [PATCH 1/2] Cleanup filtration code * made a macro for decoders, reducing code length and complexity * cleaned up the imports * cleaned up code --- src/filtration_system/mod.rs | 143 +++++++++++++++-------------------- src/searchers/bfs.rs | 6 +- src/searchers/mod.rs | 8 +- 3 files changed, 67 insertions(+), 90 deletions(-) diff --git a/src/filtration_system/mod.rs b/src/filtration_system/mod.rs index cae0db1..9b85849 100644 --- a/src/filtration_system/mod.rs +++ b/src/filtration_system/mod.rs @@ -1,32 +1,26 @@ use std::sync::mpsc::channel; use crate::checkers::CheckerTypes; -use crate::decoders::atbash_decoder::AtbashDecoder; -use crate::decoders::base32_decoder::Base32Decoder; -use crate::decoders::base58_bitcoin_decoder::Base58BitcoinDecoder; -use crate::decoders::base58_monero_decoder::Base58MoneroDecoder; -use crate::decoders::binary_decoder::BinaryDecoder; -use crate::decoders::hexadecimal_decoder::HexadecimalDecoder; use crate::DecoderResult; -use crate::decoders::base58_flickr_decoder::Base58FlickrDecoder; -use crate::decoders::base58_ripple_decoder::Base58RippleDecoder; - +use crate::decoders::crack_results::CrackResult; +use crate::decoders::interface::{Crack, Decoder}; ///! Proposal: https://broadleaf-angora-7db.notion.site/Filtration-System-7143b36a42f1466faea3077bfc7e859e ///! Given a filter object, return an array of decoders/crackers which have been filtered /// -use crate::decoders::base64_decoder::Base64Decoder; -use crate::decoders::base64_url_decoder::Base64URLDecoder; -use crate::decoders::base65536_decoder::Base65536Decoder; -use crate::decoders::base91_decoder::Base91Decoder; -use crate::decoders::caesar_decoder::CaesarDecoder; -use crate::decoders::citrix_ctx1_decoder::CitrixCTX1Decoder; -use crate::decoders::crack_results::CrackResult; -use crate::decoders::interface::{Crack, Decoder}; -use crate::decoders::morse_code::MorseCodeDecoder; -use crate::decoders::railfence_decoder::RailfenceDecoder; -use crate::decoders::reverse_decoder::ReverseDecoder; -use crate::decoders::url_decoder::URLDecoder; + +/// Import all of the decoders +use crate::decoders::{ + atbash_decoder::AtbashDecoder, base32_decoder::Base32Decoder, + base58_bitcoin_decoder::Base58BitcoinDecoder, base58_flickr_decoder::Base58FlickrDecoder, + base58_monero_decoder::Base58MoneroDecoder, base58_ripple_decoder::Base58RippleDecoder, + base64_decoder::Base64Decoder, base64_url_decoder::Base64URLDecoder, + base65536_decoder::Base65536Decoder, base91_decoder::Base91Decoder, + binary_decoder::BinaryDecoder, caesar_decoder::CaesarDecoder, + citrix_ctx1_decoder::CitrixCTX1Decoder, hexadecimal_decoder::HexadecimalDecoder, + morse_code::MorseCodeDecoder, railfence_decoder::RailfenceDecoder, + reverse_decoder::ReverseDecoder, url_decoder::URLDecoder, +}; use log::trace; use rayon::prelude::*; @@ -50,100 +44,83 @@ impl Decoders { /// https://doc.rust-lang.org/book/ch17-02-trait-objects.html /// Which allows us to have multiple different structs in the same vector /// But each struct shares the same `.crack()` method, so it's fine. - pub fn run(&self, text: &str, checker: CheckerTypes) -> MyResults { + pub fn run(&self, text: &str, checker: CheckerTypes) -> CrackResults { trace!("Running .crack() on all decoders"); let (sender, receiver) = channel(); self.components .into_par_iter() - .try_for_each_with(sender, |s, i| { + .try_for_each_with(sender, |s, i| -> Option<()> { let results = i.crack(text, &checker); if results.success { - s.send(results).expect("expected no send error!"); - // returning None short-circuits the iterator - // we don't process any further as we got success - return None; + s.send(results).expect("Failed to send results!"); + return None; // Short-circuit the iterator } - s.send(results).expect("expected no send error!"); - // return Some(()) to indicate that continue processing - Some(()) + s.send(results).expect("Failed to send results!"); + Some(()) // Continue the iterator }); let mut all_results: Vec = Vec::new(); - while let Ok(result) = receiver.recv() { - // if we recv success, break. + for result in receiver.iter() { if result.success { - return MyResults::Break(result); + return CrackResults::Break(result); } - all_results.push(result) + all_results.push(result); } - MyResults::Continue(all_results) + CrackResults::Continue(all_results) } } -/// [`Enum`] for our custom results. -/// if our checker succeed, we return `Break` variant contining [`CrackResult`] -/// else we return `Continue` with the decoded results. -pub enum MyResults { - /// Variant containing successful [`CrackResult`] +/// Enum representing the result of a cracking operation. +/// If the checker succeeds, it returns the `Break` variant containing `CrackResult`. +/// Otherwise, it returns the `Continue` variant with a vector of `CrackResult` for further processing. +pub enum CrackResults { + /// Variant containing a successful `CrackResult`. Break(CrackResult), - /// Contains [`Vec`] of [`CrackResult`] for further processing + /// Contains a vector of `CrackResult` for further processing. Continue(Vec), } -impl MyResults { - /// named with _ to pass dead_code warning - /// as we aren't using it, it's just used in tests - pub fn _break_value(self) -> Option { +impl CrackResults { + #[allow(dead_code)] + pub fn break_value(self) -> Option { match self { - MyResults::Break(val) => Some(val), - MyResults::Continue(_) => None, + CrackResults::Break(val) => Some(val), + CrackResults::Continue(_) => None, } } } +macro_rules! create_decoder { + ($decoder:ty) => { + Box::new(Decoder::<$decoder>::new()) + }; +} + /// Currently takes no args as this is just a spike to get all the basic functionality working pub fn filter_and_get_decoders(_text_struct: &DecoderResult) -> Decoders { trace!("Filtering and getting all decoders"); - let binary = Decoder::::new(); - let hexadecimal = Decoder::::new(); - let base58_bitcoin = Decoder::::new(); - let base58_monero = Decoder::::new(); - let base58_ripple = Decoder::::new(); - let base58_flickr = Decoder::::new(); - let base64 = Decoder::::new(); - let base91 = Decoder::::new(); - let base64_url = Decoder::::new(); - let base65536 = Decoder::::new(); - let citrix_ctx1 = Decoder::::new(); - let url = Decoder::::new(); - let base32 = Decoder::::new(); - let reversedecoder = Decoder::::new(); - let morsecodedecoder = Decoder::::new(); - let atbashdecoder = Decoder::::new(); - let caesardecoder = Decoder::::new(); - let railfencedecoder = Decoder::::new(); Decoders { components: vec![ - Box::new(reversedecoder), - Box::new(base64), - Box::new(base58_bitcoin), - Box::new(base58_monero), - Box::new(base58_ripple), - Box::new(base58_flickr), - Box::new(base91), - Box::new(base65536), - Box::new(binary), - Box::new(hexadecimal), - Box::new(base32), - Box::new(morsecodedecoder), - Box::new(atbashdecoder), - Box::new(caesardecoder), - Box::new(railfencedecoder), - Box::new(citrix_ctx1), - Box::new(url), - Box::new(base64_url), + create_decoder!(ReverseDecoder), + create_decoder!(Base64Decoder), + create_decoder!(Base58BitcoinDecoder), + create_decoder!(Base58MoneroDecoder), + create_decoder!(Base58RippleDecoder), + create_decoder!(Base58FlickrDecoder), + create_decoder!(Base91Decoder), + create_decoder!(Base65536Decoder), + create_decoder!(BinaryDecoder), + create_decoder!(HexadecimalDecoder), + create_decoder!(Base32Decoder), + create_decoder!(MorseCodeDecoder), + create_decoder!(AtbashDecoder), + create_decoder!(CaesarDecoder), + create_decoder!(RailfenceDecoder), + create_decoder!(CitrixCTX1Decoder), + create_decoder!(URLDecoder), + create_decoder!(Base64URLDecoder), ], } } diff --git a/src/searchers/bfs.rs b/src/searchers/bfs.rs index d074c98..6eff5e5 100644 --- a/src/searchers/bfs.rs +++ b/src/searchers/bfs.rs @@ -1,5 +1,5 @@ use crate::cli_pretty_printing::decoded_how_many_times; -use crate::filtration_system::MyResults; +use crate::filtration_system::CrackResults; use crossbeam::channel::Sender; use log::trace; @@ -35,7 +35,7 @@ pub fn bfs(input: String, result_sender: Sender>, stop: Ar match res { // if it's Break variant, we have cracked the text successfully // so just stop processing further. - MyResults::Break(res) => { + CrackResults::Break(res) => { let mut decoders_used = current_string.path; let text = res.unencrypted_text.clone().unwrap_or_default(); decoders_used.push(res); @@ -53,7 +53,7 @@ pub fn bfs(input: String, result_sender: Sender>, stop: Ar stop.store(true, std::sync::atomic::Ordering::Relaxed); None // short-circuits the iterator } - MyResults::Continue(results_vec) => { + CrackResults::Continue(results_vec) => { new_strings.extend(results_vec.into_iter().flat_map(|mut r| { let mut decoders_used = current_string.path.clone(); // text is a vector of strings diff --git a/src/searchers/mod.rs b/src/searchers/mod.rs index 9a2d774..09b9695 100644 --- a/src/searchers/mod.rs +++ b/src/searchers/mod.rs @@ -14,7 +14,7 @@ use crate::checkers::athena::Athena; use crate::checkers::checker_type::{Check, Checker}; use crate::checkers::CheckerTypes; use crate::config::get_config; -use crate::filtration_system::{filter_and_get_decoders, MyResults}; +use crate::filtration_system::{filter_and_get_decoders, CrackResults}; use crate::{timer, DecoderResult}; /// This module provides access to the breadth first search /// which searches for the plaintext. @@ -67,7 +67,7 @@ pub fn search_for_plaintext(input: String) -> Option { /// Performs the decodings by getting all of the decoders /// and calling `.run` which in turn loops through them and calls /// `.crack()`. -fn perform_decoding(text: &DecoderResult) -> MyResults { +fn perform_decoding(text: &DecoderResult) -> CrackResults { let decoders = filter_and_get_decoders(text); let athena_checker = Checker::::new(); let checker = CheckerTypes::CheckAthena(athena_checker); @@ -105,7 +105,7 @@ mod tests { let result = perform_decoding(&dc); assert!( result - ._break_value() + .break_value() .expect("expected successful value, none found") .success ); @@ -116,6 +116,6 @@ mod tests { // Some decoders like base64 return even when the string is empty. let dc = DecoderResult::_new(""); let result = perform_decoding(&dc); - assert!(result._break_value().is_none()); + assert!(result.break_value().is_none()); } } From 56d98ab22128c9451e8440b3dcc03355e5ab50c4 Mon Sep 17 00:00:00 2001 From: SkeletalDemise <29117662+SkeletalDemise@users.noreply.github.com> Date: Wed, 17 May 2023 05:01:07 -0700 Subject: [PATCH 2/2] Add docs --- src/filtration_system/mod.rs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/filtration_system/mod.rs b/src/filtration_system/mod.rs index 9b85849..65f1e86 100644 --- a/src/filtration_system/mod.rs +++ b/src/filtration_system/mod.rs @@ -84,6 +84,7 @@ pub enum CrackResults { impl CrackResults { #[allow(dead_code)] + /// Returns the `CrackResult` if the checker succeeds. pub fn break_value(self) -> Option { match self { CrackResults::Break(val) => Some(val), @@ -92,6 +93,7 @@ impl CrackResults { } } +/// Create a decoder and return it as a Box macro_rules! create_decoder { ($decoder:ty) => { Box::new(Decoder::<$decoder>::new())