ares/decoders/
base65536_decoder.rs1use crate::checkers::CheckerTypes;
7use crate::decoders::interface::check_string_success;
8
9use super::crack_results::CrackResult;
10use super::interface::Crack;
11use super::interface::Decoder;
12
13use log::{debug, info, trace};
14
15pub struct Base65536Decoder;
34
35impl Crack for Decoder<Base65536Decoder> {
36 fn new() -> Decoder<Base65536Decoder> {
37 Decoder {
38 name: "Base65536",
39 description: "Base65536 is a binary encoding optimised for UTF-32-encoded text. Base65536 uses only \"safe\" Unicode code points - no unassigned code points, no whitespace, no control characters, etc.",
40 link: "https://github.com/qntm/base65536",
41 tags: vec!["base65536", "decoder", "base"],
42 popularity: 0.1,
43 phantom: std::marker::PhantomData,
44 }
45 }
46
47 fn crack(&self, text: &str, checker: &CheckerTypes) -> CrackResult {
51 trace!("Trying base65536 with text {:?}", text);
52 let decoded_text: Option<String> = decode_base65536_no_error_handling(text);
53
54 trace!("Decoded text for base65536: {:?}", decoded_text);
55 let mut results = CrackResult::new(self, text.to_string());
56
57 if decoded_text.is_none() {
58 debug!("Failed to decode base65536 because Base65536Decoder::decode_base65536_no_error_handling returned None");
59 return results;
60 }
61
62 let decoded_text = decoded_text.unwrap();
63 if !check_string_success(&decoded_text, text) {
64 info!(
65 "Failed to decode base65536 because check_string_success returned false on string {}",
66 decoded_text
67 );
68 return results;
69 }
70
71 let checker_result = checker.check(&decoded_text);
72 results.unencrypted_text = Some(vec![decoded_text]);
73
74 results.update_checker(&checker_result);
75
76 results
77 }
78 fn get_tags(&self) -> &Vec<&str> {
80 &self.tags
81 }
82 fn get_name(&self) -> &str {
84 self.name
85 }
86}
87
88fn decode_base65536_no_error_handling(text: &str) -> Option<String> {
90 if let Ok(decoded_text) = base65536::decode(text, false) {
93 return Some(String::from_utf8_lossy(&decoded_text).to_string());
94 }
95 None
96}
97
98#[cfg(test)]
99mod tests {
100 use super::Base65536Decoder;
101 use crate::{
102 checkers::{
103 athena::Athena,
104 checker_type::{Check, Checker},
105 CheckerTypes,
106 },
107 decoders::interface::{Crack, Decoder},
108 };
109
110 fn get_athena_checker() -> CheckerTypes {
112 let athena_checker = Checker::<Athena>::new();
113 CheckerTypes::CheckAthena(athena_checker)
114 }
115
116 #[test]
117 fn base65536_decodes_successfully() {
118 let base65536_decoder = Decoder::<Base65536Decoder>::new();
120 let result = base65536_decoder.crack("𒅓鹨𖡮𒀠啦ꍢ顡啫𓍱𓁡𠁴唬𓍪鱤啥𖥭𔐠𔕯ᔮ", &get_athena_checker());
121 assert_eq!(
122 result.unencrypted_text.unwrap()[0],
123 "Sphinx of black quartz, judge my vow."
124 );
125 }
126
127 #[test]
128 fn base65536_handles_panics() {
129 let base65536_decoder = Decoder::<Base65536Decoder>::new();
132 let result = base65536_decoder
133 .crack(
134 "hello my name is panicky mc panic face!",
135 &get_athena_checker(),
136 )
137 .unencrypted_text;
138 assert!(result.is_none());
139 }
140
141 #[test]
142 fn base65536_handles_panic_if_empty_string() {
143 let base65536_decoder = Decoder::<Base65536Decoder>::new();
146 let result = base65536_decoder
147 .crack("", &get_athena_checker())
148 .unencrypted_text;
149 assert!(result.is_none());
150 }
151
152 #[test]
153 fn base65536_handles_panic_if_emoji() {
154 let base65536_decoder = Decoder::<Base65536Decoder>::new();
157 let result = base65536_decoder
158 .crack("😂", &get_athena_checker())
159 .unencrypted_text;
160 assert!(result.is_none());
161 }
162}