ares/decoders/
reverse_decoder.rs

1use crate::checkers::CheckerTypes;
2
3use super::crack_results::CrackResult;
4///! Reverses the input string
5///! Performs error handling and returns a string
6///! Call reverse_decoder.crack to use. It returns option<String> and check with
7///! `result.is_some()` to see if it returned okay.
8///
9use super::interface::Crack;
10use super::interface::Decoder;
11
12use log::trace;
13/// The Reverse decoder is a decoder that reverses the input string.
14/// ```rust
15/// use ares::decoders::reverse_decoder::ReverseDecoder;
16/// use ares::decoders::interface::{Crack, Decoder};
17/// use ares::config::{set_global_config, Config};
18/// use ares::checkers::{athena::Athena, CheckerTypes, checker_type::{Check, Checker}};
19///
20/// let reversedecoder = Decoder::<ReverseDecoder>::new();
21/// let athena_checker = Checker::<Athena>::new();
22/// let checker = CheckerTypes::CheckAthena(athena_checker);
23///
24/// let result = reversedecoder.crack("stac", &checker).unencrypted_text;
25/// assert!(result.is_some());
26/// assert_eq!(result.unwrap()[0], "cats");
27/// ```
28pub struct ReverseDecoder;
29
30impl Crack for Decoder<ReverseDecoder> {
31    fn new() -> Decoder<ReverseDecoder> {
32        Decoder {
33            name: "Reverse",
34            description: "Reverses a string. stac -> cats",
35            link: "http://string-functions.com/reverse.aspx",
36            tags: vec!["reverse", "decoder", "reciprocal"],
37            // I have never seen a reversed string in a CTF
38            // or otherwise
39            popularity: 0.2,
40            phantom: std::marker::PhantomData,
41        }
42    }
43
44    /// This function does the actual decoding
45    /// It returns an Option<string> if it was successful
46    /// Else the Option returns nothing and the error is logged in Trace
47    fn crack(&self, text: &str, checker: &CheckerTypes) -> CrackResult {
48        trace!("Running reverse string");
49        let mut result = CrackResult::new(self, text.to_string());
50        if text.is_empty() {
51            return result;
52        }
53        let rev_str: String = text.chars().rev().collect();
54        let checker_res = checker.check(&rev_str);
55
56        result.unencrypted_text = Some(vec![rev_str]);
57        result.update_checker(&checker_res);
58        result
59    }
60    /// Gets all tags for this decoder
61    fn get_tags(&self) -> &Vec<&str> {
62        &self.tags
63    }
64    /// Gets the name for the current decoder
65    fn get_name(&self) -> &str {
66        self.name
67    }
68}
69
70#[cfg(test)]
71mod tests {
72    use super::*;
73    use crate::{
74        checkers::{
75            athena::Athena,
76            checker_type::{Check, Checker},
77        },
78        decoders::interface::Crack,
79    };
80
81    // helper for tests
82    fn get_athena_checker() -> CheckerTypes {
83        let athena_checker = Checker::<Athena>::new();
84        CheckerTypes::CheckAthena(athena_checker)
85    }
86
87    #[test]
88    fn returns_success() {
89        let reverse_decoder = Decoder::<ReverseDecoder>::new();
90        let result = reverse_decoder
91            .crack("stac", &get_athena_checker())
92            .unencrypted_text
93            .expect("No unencrypted string for reverse decoder");
94        assert_eq!(result[0], "cats");
95    }
96
97    #[test]
98    fn returns_nothing() {
99        let reverse_decoder = Decoder::<ReverseDecoder>::new();
100        let result = reverse_decoder
101            .crack("", &get_athena_checker())
102            .unencrypted_text;
103        assert!(result.is_none());
104    }
105}