ares/decoders/
binary_decoder.rs1use crate::checkers::CheckerTypes;
2use crate::decoders::interface::check_string_success;
3
4use super::crack_results::CrackResult;
5use super::interface::Crack;
6use super::interface::Decoder;
7
8use log::{debug, info, trace};
9
10pub struct BinaryDecoder;
12
13impl Crack for Decoder<BinaryDecoder> {
14 fn new() -> Decoder<BinaryDecoder> {
15 Decoder {
16 name: "Binary",
17 description: "A binary code represents text, computer processor instructions, or any other data using a two-symbol system. The two-symbol system used is often \"0\" and \"1\" from the binary number system. The binary code assigns a pattern of binary digits, also known as bits, to each character, instruction, etc.",
18 link: "https://en.wikipedia.org/wiki/Binary_code",
19 tags: vec!["binary", "base", "decoder"],
20 popularity: 1.0,
21 phantom: std::marker::PhantomData,
22 }
23 }
24
25 fn crack(&self, text: &str, checker: &CheckerTypes) -> CrackResult {
29 trace!("Trying binary with text {:?}", text);
30 let mut results = CrackResult::new(self, text.to_string());
31 let mut decoded_strings = Vec::new();
32
33 for shift in 1..25 {
34 let decoded_text = binary_to_string(text, shift);
35
36 decoded_strings.push(decoded_text);
37 let borrowed_decoded_text = &decoded_strings[decoded_strings.len() - 1];
38 if !check_string_success(borrowed_decoded_text, text) {
39 debug!(
40 "Failed to decode binary because binary returned false on string {}. This means the string is 'funny' as it wasn't modified.",
41 borrowed_decoded_text
42 );
43 return results;
44 }
45 let checker_result = checker.check(borrowed_decoded_text);
46 if checker_result.is_identified {
48 info!("Found a match with binary bit {}", shift);
49 results.unencrypted_text = Some(vec![borrowed_decoded_text.to_string()]);
50 results.update_checker(&checker_result);
51 return results;
52 }
53 }
54 results.unencrypted_text = Some(decoded_strings);
55 results
56 }
57 fn get_tags(&self) -> &Vec<&str> {
59 &self.tags
60 }
61 fn get_name(&self) -> &str {
63 self.name
64 }
65}
66
67fn binary_to_string(binary: &str, bit: u8) -> String {
70 let mut out = String::new();
71 let mut iter = binary.as_bytes().iter().filter_map(|byte| match byte {
72 b'0' => Some(0),
73 b'1' => Some(1),
74 _ => None,
75 });
76 loop {
77 let byte = iter
78 .by_ref()
79 .take(usize::from(bit))
80 .reduce(|acc, elem| (acc << 1) | elem);
81 match byte {
82 Some(byte) => out.push(char::from(byte)),
83 None => break,
84 }
85 }
86 out
87}
88
89#[cfg(test)]
90mod tests {
91 use super::binary_to_string;
92 use super::BinaryDecoder;
93 use crate::{
94 checkers::{
95 athena::Athena,
96 checker_type::{Check, Checker},
97 CheckerTypes,
98 },
99 decoders::interface::{Crack, Decoder},
100 };
101
102 fn get_athena_checker() -> CheckerTypes {
104 let athena_checker = Checker::<Athena>::new();
105 CheckerTypes::CheckAthena(athena_checker)
106 }
107
108 #[test]
109 #[ignore]
110 fn binary_bit_7_decodes_successfully() {
111 let decoder = Decoder::<BinaryDecoder>::new();
113 let input = "1010011111000011010001101001110111011110000100000110111111001100100000110001011011001100001110001111010110100000111000111101011100001111001011101001111010010110001000001101010111010111001001100111110010101000001101101111100101000001110110110111111101110101110";
114 let expected = "Sphinx of black quartz, judge my vow.";
115
116 println!("Input text length: {}", input.len());
117 println!("Input text: {:?}", input);
118
119 for bit in 5..10 {
121 let decoded = binary_to_string(input, bit);
122 println!("Bit length: {}, Result: {:?}", bit, decoded);
123 }
124
125 let manual_decode = binary_to_string(input, 7);
127 println!("Manual decode with bit 7: {:?}", manual_decode);
128 println!("Manual decode length: {}", manual_decode.len());
129
130 let non_binary_chars: Vec<char> =
132 input.chars().filter(|c| *c != '0' && *c != '1').collect();
133 println!("Non-binary characters in input: {:?}", non_binary_chars);
134
135 let result = decoder.crack(input, &get_athena_checker());
136
137 if let Some(decoded_texts) = &result.unencrypted_text {
138 println!("Number of decoded texts: {}", decoded_texts.len());
139 for (i, text) in decoded_texts.iter().enumerate() {
140 println!("Decoded text {}: {:?}", i, text);
141 }
142
143 if !decoded_texts.is_empty() {
144 println!("First decoded text: {:?}", decoded_texts[0]);
145 println!("Expected text: {:?}", expected);
146 }
147 } else {
148 println!("No decoded texts found");
149 }
150
151 assert_eq!(result.unencrypted_text.unwrap()[0], expected);
152 }
153
154 #[test]
155 fn binary_bit_8_decodes_successfully() {
156 let decoder = Decoder::<BinaryDecoder>::new();
158 let result = decoder.crack("0110100001100101011011000110110001101111001000000111011101101111011100100110110001100100", &get_athena_checker());
159 assert_eq!(result.unencrypted_text.unwrap()[0], "hello world");
160 }
161
162 #[test]
163 fn binary_bit_12_with_delimiters_decodes_successfully() {
164 let decoder = Decoder::<BinaryDecoder>::new();
166 let result = decoder.crack("000001101000;000001110100;000001110100;000001110000;000001110011;000000111010;000000101111;000000101111;000001110111;000001110111;000001110111;000000101110;000001100111;000001101111;000001101111;000001100111;000001101100;000001100101;000000101110;000001100011;000001101111;000001101101", &get_athena_checker());
167 assert_eq!(
168 result.unencrypted_text.unwrap()[0],
169 "https://www.google.com"
170 );
171 }
172
173 #[test]
174 fn binary_bit_15_with_a_lot_of_delimiters_decodes_successfully() {
175 let decoder = Decoder::<BinaryDecoder>::new();
177 let result = decoder.crack(r"000+00\0001\010||100;00[000]00{}011'010'00;0'000:000:0110:10;01;0.00.000.001.11.00.11;000 ,000,000,1 00,000;0$00 0$000 0$1101$001;0!00 !00000!1 1100!1 1;000`000`000`100~000;00~000-00=0110_0011;00\\000\00\/011/0111/1 ;00?000<>000}110{11150;09008goodluck003005011h10110;00,00m00b0011f0s11f11;0h00j0r00c001t1011*00;00* 000%00011#101301;0070040 08001-1101=00;000_0 0.0001,100 .101;00090006 00113001 ~00;00d00-0 000-0101=110", &get_athena_checker());
178 assert_eq!(result.unencrypted_text.unwrap()[0], "This is convoluted.");
179 }
180
181 #[test]
182 fn binary_handles_panics() {
183 let binary_decoder = Decoder::<BinaryDecoder>::new();
186 let result = binary_decoder
187 .crack(
188 "hello my name is panicky mc panic face!",
189 &get_athena_checker(),
190 )
191 .unencrypted_text;
192 assert!(result.is_none());
193 }
194
195 #[test]
196 fn binary_handles_panic_if_empty_string() {
197 let citrix_ctx1_decoder = Decoder::<BinaryDecoder>::new();
200 let result = citrix_ctx1_decoder
201 .crack("", &get_athena_checker())
202 .unencrypted_text;
203 assert!(result.is_none());
204 }
205
206 #[test]
207 fn binary_handles_panic_if_emoji() {
208 let base64_url_decoder = Decoder::<BinaryDecoder>::new();
211 let result = base64_url_decoder
212 .crack("😂", &get_athena_checker())
213 .unencrypted_text;
214 assert!(result.is_none());
215 }
216}