ares/decoders/
base32_decoder.rs1use crate::checkers::CheckerTypes;
2use crate::decoders::interface::check_string_success;
3
4use super::crack_results::CrackResult;
5use super::interface::Crack;
11use super::interface::Decoder;
12
13use data_encoding::BASE32;
14use log::{debug, info, trace};
15
16pub struct Base32Decoder;
35
36impl Crack for Decoder<Base32Decoder> {
37 fn new() -> Decoder<Base32Decoder> {
38 Decoder {
39 name: "Base32",
40 description: "Base32 is a group of binary-to-text encoding schemes that represent binary data (more specifically, a sequence of 8-bit bytes) in an ASCII string format by translating the data into a radix-32 representation.",
41 link: "https://en.wikipedia.org/wiki/Base32",
42 tags: vec!["base32", "decoder", "base"],
43 popularity: 0.8,
44 phantom: std::marker::PhantomData,
45 }
46 }
47
48 fn crack(&self, text: &str, checker: &CheckerTypes) -> CrackResult {
52 trace!("Trying Base32 with text {:?}", text);
53 let decoded_text = decode_base32_no_error_handling(text);
54 let mut results = CrackResult::new(self, text.to_string());
55
56 if decoded_text.is_none() {
57 debug!("Failed to decode base32 because Base32Decoder::decode_base32_no_error_handling returned None");
58 return results;
59 }
60
61 let decoded_text = decoded_text.unwrap();
62 if !check_string_success(&decoded_text, text) {
63 info!(
64 "Failed to decode base32 because check_string_success returned false on string {}",
65 decoded_text
66 );
67 return results;
68 }
69
70 let checker_result = checker.check(&decoded_text);
71 results.unencrypted_text = Some(vec![decoded_text]);
72
73 results.update_checker(&checker_result);
74
75 results
76 }
77 fn get_tags(&self) -> &Vec<&str> {
79 &self.tags
80 }
81 fn get_name(&self) -> &str {
83 self.name
84 }
85}
86
87fn decode_base32_no_error_handling(text: &str) -> Option<String> {
89 if let Ok(decoded_text) = &BASE32.decode(text.as_bytes()) {
92 return Some(String::from_utf8_lossy(decoded_text).to_string());
93 }
94 None
95}
96
97#[cfg(test)]
98mod tests {
99 use super::Base32Decoder;
100 use crate::{
101 checkers::{
102 athena::Athena,
103 checker_type::{Check, Checker},
104 CheckerTypes,
105 },
106 decoders::interface::{Crack, Decoder},
107 };
108
109 fn get_athena_checker() -> CheckerTypes {
111 let athena_checker = Checker::<Athena>::new();
112 CheckerTypes::CheckAthena(athena_checker)
113 }
114
115 #[test]
116 fn successful_decoding() {
117 let base32_decoder = Decoder::<Base32Decoder>::new();
118
119 let result = base32_decoder.crack("NBSWY3DPEB3W64TMMQ======", &get_athena_checker());
120 let decoded_str = &result
121 .unencrypted_text
122 .expect("No unencrypted text for base32");
123 assert_eq!(decoded_str[0], "hello world");
124 }
125
126 #[test]
127 fn base32_decode_empty_string() {
128 let base32_decoder = Decoder::<Base32Decoder>::new();
131 let result = base32_decoder
132 .crack("", &get_athena_checker())
133 .unencrypted_text;
134 assert!(result.is_none());
135 }
136
137 #[test]
138 fn base32_decode_handles_panics() {
139 let base32_decoder = Decoder::<Base32Decoder>::new();
140 let result = base32_decoder
141 .crack(
142 "hello my name is panicky mc panic face!",
143 &get_athena_checker(),
144 )
145 .unencrypted_text;
146 if result.is_some() {
147 panic!("Decode_base32 did not return an option with Some<t>.")
148 } else {
149 assert_eq!(true, true);
153 }
154 }
155
156 #[test]
157 fn base32_handle_panic_if_empty_string() {
158 let base32_decoder = Decoder::<Base32Decoder>::new();
159 let result = base32_decoder
160 .crack("", &get_athena_checker())
161 .unencrypted_text;
162 if result.is_some() {
163 assert_eq!(true, true);
164 }
165 }
166
167 #[test]
168 fn base32_work_if_string_not_base32() {
169 let base32_decoder = Decoder::<Base32Decoder>::new();
175 let result = base32_decoder
176 .crack("hello good day!", &get_athena_checker())
177 .unencrypted_text;
178 if result.is_some() {
179 assert_eq!(true, true);
180 }
181 }
182
183 #[test]
184 fn base32_handle_panic_if_emoji() {
185 let base32_decoder = Decoder::<Base32Decoder>::new();
186 let result = base32_decoder
187 .crack("😂", &get_athena_checker())
188 .unencrypted_text;
189 if result.is_some() {
190 assert_eq!(true, true);
191 }
192 }
193}