diff --git a/.gitignore b/.gitignore index ad67955..0728338 100644 --- a/.gitignore +++ b/.gitignore @@ -19,3 +19,8 @@ target # and can be added to the global gitignore or merged into this file. For a more nuclear # option (not recommended) you can uncomment the following to ignore the entire idea folder. #.idea/ + + +# Added by cargo + +/target diff --git a/Cargo.lock b/Cargo.lock new file mode 100644 index 0000000..499aaed --- /dev/null +++ b/Cargo.lock @@ -0,0 +1,92 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 4 + +[[package]] +name = "CrackaCesar" +version = "0.1.0" +dependencies = [ + "colored", +] + +[[package]] +name = "colored" +version = "3.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fde0e0ec90c9dfb3b4b1a0891a7dcd0e2bffde2f7efed5fe7c9bb00e5bfb915e" +dependencies = [ + "windows-sys", +] + +[[package]] +name = "windows-sys" +version = "0.59.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b" +dependencies = [ + "windows-targets", +] + +[[package]] +name = "windows-targets" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973" +dependencies = [ + "windows_aarch64_gnullvm", + "windows_aarch64_msvc", + "windows_i686_gnu", + "windows_i686_gnullvm", + "windows_i686_msvc", + "windows_x86_64_gnu", + "windows_x86_64_gnullvm", + "windows_x86_64_msvc", +] + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" + +[[package]] +name = "windows_i686_gnu" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b" + +[[package]] +name = "windows_i686_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" + +[[package]] +name = "windows_i686_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" diff --git a/Cargo.toml b/Cargo.toml new file mode 100644 index 0000000..c0a2eb5 --- /dev/null +++ b/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "CrackaCesar" +version = "0.1.0" +edition = "2024" + +[dependencies] +colored = "3.0.0" diff --git a/src/main.rs b/src/main.rs new file mode 100644 index 0000000..812ca25 --- /dev/null +++ b/src/main.rs @@ -0,0 +1,174 @@ +use std::collections::HashMap; +use std::env::args; +use std::io::stdin; +use std::process::exit; +use colored::Colorize; + + +fn main() { + let mut alphabet = HashMap::new(); + alphabet.insert(0, 'a'); + alphabet.insert(1, 'b'); + alphabet.insert(2, 'c'); + alphabet.insert(3, 'd'); + alphabet.insert(4, 'e'); + alphabet.insert(5, 'f'); + alphabet.insert(6, 'g'); + alphabet.insert(7, 'h'); + alphabet.insert(8, 'i'); + alphabet.insert(9, 'j'); + alphabet.insert(10, 'k'); + alphabet.insert(11, 'l'); + alphabet.insert(12, 'm'); + alphabet.insert(13, 'n'); + alphabet.insert(14, 'o'); + alphabet.insert(15, 'p'); + alphabet.insert(16, 'q'); + alphabet.insert(17, 'r'); + alphabet.insert(18, 's'); + alphabet.insert(19, 't'); + alphabet.insert(20, 'u'); + alphabet.insert(21, 'v'); + alphabet.insert(22, 'w'); + alphabet.insert(23, 'x'); + alphabet.insert(24, 'y'); + alphabet.insert(25, 'z'); + + let mut cracking_key = 0; + + let common_short_words = vec![ + "i", + "the", + "an", + "full", + "bug", + "of", + "for", + "you", + "not", + "are", + "new", + "was", + "can", + "has", + "out", + "use", + "may", + "our", + "see", + "his", + "him", + "her", + "any", + "but", + "and", + "all", + "one", + "two", + "we", + ]; + + + let args: Vec = args().collect(); + if args.len() < 2 { + println!(" +USAGE: +CrackaCesar cipher text + "); + exit(1); + } + let mut cipher_vec = args.clone(); + cipher_vec.remove(0); + let cipher_text = args[1..].join(" "); + let mut short_words = Vec::new(); + for word in cipher_vec{ + if word.len() < 4{ + short_words.push(word.clone()); + } + } + let mut cracked = false; + let mut failed_decrypt_words = Vec::new(); + for key in 0..26{ + let mut decrypted_words = Vec::new(); + for oword in short_words.clone(){ + let word = oword.to_lowercase(); + let mut addition_word = String::new(); + let chars = word.chars(); + for letter in chars{ + if letter.is_ascii_alphabetic(){ + let mut letter_orig_index = 0; + for (key, value) in alphabet.iter(){ + if value == &letter{ + letter_orig_index = *key; + } + } + let mut add_letter_index:i32 = letter_orig_index + key; + if add_letter_index > 25{ + add_letter_index = add_letter_index - 26; + } + addition_word.push(alphabet[&add_letter_index]); + } + } + decrypted_words.push(addition_word.clone()); + failed_decrypt_words.push(format!("{} => {}", key, &addition_word)); + } + let success_num = decrypted_words.len(); + let mut valid_num: usize = 1; + for word in &decrypted_words{ + if common_short_words.contains(&word.as_str()){ + valid_num += 1; + } + } + if valid_num >= success_num{ + println!("{}\n", "key found!".green()); + cracked = true; + cracking_key = key; + } + else if valid_num >= success_num / 2{ + println!("{}", "possible key found!".green()); + println!("{} => {}", key, decrypted_words.join("\n")); + let mut crack_res = String::new(); + println!("try to decypt the whole string with this key?"); + stdin().read_line(&mut crack_res).unwrap(); + if crack_res.to_lowercase().contains("y"){ + cracked = true; + cracking_key = key; + } + } + } + if !cracked{ + println!("{}", "couldn't automatically determine a cracking key...".red()); + println!("{}", failed_decrypt_words.join("\n\n")); + let mut key_response = String::new(); + println!("key that resulted in real words? (enter no if none are)"); + stdin().read_line(&mut key_response).unwrap(); + if key_response.to_lowercase().contains("n"){ + println!("{}", "sorry about that, we can't seem to find the right key...".red()); + exit(1); + } + cracking_key = key_response.trim().parse().unwrap(); + } + + let mut cracked_string = String::new(); + for oletter in cipher_text.chars(){ + if oletter.is_alphabetic(){ + let letter = oletter.to_ascii_lowercase(); + let mut orig_index = 0; + for (key, value) in alphabet.iter(){ + if value == &letter{ + orig_index = *key; + } + } + let mut new_index: i32 = orig_index + cracking_key; + if new_index > 25{ + new_index -= 26; + } + let new_letteer = alphabet[&new_index]; + cracked_string.push(new_letteer); + } + else{ + cracked_string.push(oletter); + } + } + println!("{}\n{}", "Decdrypted cipher:".green() ,cracked_string); +}