diff --git a/common/src/lib.rs b/common/src/lib.rs index c3dac5f..96376fc 100644 --- a/common/src/lib.rs +++ b/common/src/lib.rs @@ -3,12 +3,20 @@ use std::ascii::escape_default; use std::iter::repeat; pub fn escape(text: &[u8]) -> String { - String::from_utf8(text.iter().map(|ch| escape_default(ch.clone())).flatten().collect()).unwrap() + String::from_utf8( + text.iter() + .map(|ch| escape_default(ch.clone())) + .flatten() + .collect(), + ) + .unwrap() } pub fn score(plaintext: &[u8]) -> u32 { - let ranking = [24, 7, 15, 17, 26, 11, 10, 19, 22, 4, 5, 16, 13, - 21, 23, 8, 2, 18, 20, 25, 14, 6, 12, 3, 9, 1]; + let ranking = [ + 24, 7, 15, 17, 26, 11, 10, 19, 22, 4, 5, 16, 13, 21, 23, 8, 2, 18, 20, 25, 14, 6, 12, 3, 9, + 1, + ]; let mut score = 0; for ch in plaintext.iter() { @@ -27,11 +35,14 @@ pub fn score(plaintext: &[u8]) -> u32 { } pub fn hamming(v1: &[u8], v2: &[u8]) -> u32 { - v1.iter().zip(v2.iter()).map(|(a, b)| a ^ b) + v1.iter() + .zip(v2.iter()) + .map(|(a, b)| a ^ b) .map(|x| ((x & 0xaa) >> 1) + (x & 0x55)) .map(|x| ((x & 0xcc) >> 2) + (x & 0x33)) .map(|x| ((x & 0xf0) >> 4) + (x & 0x0f)) - .map(|x| x as u32).sum() + .map(|x| x as u32) + .sum() } #[cfg(test)] @@ -86,8 +97,10 @@ pub fn break_repeating_xor_cipher(ciphertext: &[u8]) -> Vec { let mut distance = 0; let maxoffset = ciphertext.len() / length - 1; for offset in 0..maxoffset { - distance += hamming(&ciphertext[offset * length .. (offset + 1) * length], - &ciphertext[(offset + 1) * length .. (offset + 2) * length]); + distance += hamming( + &ciphertext[offset * length..(offset + 1) * length], + &ciphertext[(offset + 1) * length..(offset + 2) * length], + ); } // scale and normalize distance *= 1024; @@ -102,7 +115,11 @@ pub fn break_repeating_xor_cipher(ciphertext: &[u8]) -> Vec { let mut decryptedcolumns: Vec> = vec![]; for offset in 0..keylength { - let ciphercolumn: Vec = ciphertext[offset..].iter().step_by(keylength).cloned().collect(); + let ciphercolumn: Vec = ciphertext[offset..] + .iter() + .step_by(keylength) + .cloned() + .collect(); let (decrypted, _) = break_xor_cipher(ciphercolumn.as_slice()); decryptedcolumns.push(decrypted); } diff --git a/set1/challenge1_hex2base64/src/main.rs b/set1/challenge1_hex2base64/src/main.rs index 25f104b..34ad0ec 100644 --- a/set1/challenge1_hex2base64/src/main.rs +++ b/set1/challenge1_hex2base64/src/main.rs @@ -1,7 +1,7 @@ use log::error; +use rustc_serialize::base64::{ToBase64, STANDARD}; use rustc_serialize::hex::FromHex; -use rustc_serialize::base64::{STANDARD, ToBase64}; -use std::io::{BufRead, stdin}; +use std::io::{stdin, BufRead}; fn main() { env_logger::init(); @@ -9,7 +9,7 @@ fn main() { for line in stdin().lock().lines().filter_map(|x| x.ok()) { match line.from_hex() { Ok(v) => println!("{}", v.to_base64(STANDARD)), - Err(e) => error!("{}", e) + Err(e) => error!("{}", e), } } } @@ -22,6 +22,9 @@ mod tests { fn challenge1_hex2base64() { let v = "49276d206b696c6c696e6720796f757220627261696e206c696b65206120706f69736f6e6f7573206d757368726f6f6d".from_hex().unwrap(); let r = v.to_base64(STANDARD); - assert_eq!(r, "SSdtIGtpbGxpbmcgeW91ciBicmFpbiBsaWtlIGEgcG9pc29ub3VzIG11c2hyb29t"); + assert_eq!( + r, + "SSdtIGtpbGxpbmcgeW91ciBicmFpbiBsaWtlIGEgcG9pc29ub3VzIG11c2hyb29t" + ); } } diff --git a/set1/challenge2_fixed_xor/src/main.rs b/set1/challenge2_fixed_xor/src/main.rs index 8082833..cd2de51 100644 --- a/set1/challenge2_fixed_xor/src/main.rs +++ b/set1/challenge2_fixed_xor/src/main.rs @@ -1,11 +1,14 @@ use common::fixed_xor_cipher; use log::error; use rustc_serialize::hex::{FromHex, ToHex}; -use std::io::{BufRead, stdin}; +use std::io::{stdin, BufRead}; struct Pairwise(T); -impl Iterator for Pairwise where T: Iterator { +impl Iterator for Pairwise +where + T: Iterator, +{ type Item = (T::Item, T::Item); fn next(&mut self) -> Option { @@ -22,9 +25,12 @@ fn main() { for (line1, line2) in Pairwise(stdin().lock().lines().filter_map(|x| x.ok())) { match (line1.from_hex(), line2.from_hex()) { - (Ok(v1), Ok(v2)) => println!("{}", fixed_xor_cipher(v1.as_slice(), v2.as_slice()).to_hex()), + (Ok(v1), Ok(v2)) => println!( + "{}", + fixed_xor_cipher(v1.as_slice(), v2.as_slice()).to_hex() + ), (Err(e), _) => error!("{}", e), - (_, Err(e)) => error!("{}", e) + (_, Err(e)) => error!("{}", e), } } } diff --git a/set1/challenge3_xor_cipher/src/main.rs b/set1/challenge3_xor_cipher/src/main.rs index 59114ac..749399c 100644 --- a/set1/challenge3_xor_cipher/src/main.rs +++ b/set1/challenge3_xor_cipher/src/main.rs @@ -1,7 +1,7 @@ use common::break_xor_cipher; use log::error; use rustc_serialize::hex::FromHex; -use std::io::{BufRead, stdin}; +use std::io::{stdin, BufRead}; fn main() { env_logger::init(); @@ -12,10 +12,10 @@ fn main() { let (decrypted, _) = break_xor_cipher(ciphertext.as_slice()); match String::from_utf8(decrypted) { Ok(s) => println!("{}", s), - Err(e) => error!("{}", e) + Err(e) => error!("{}", e), } } - Err(e) => error!("{}", e) + Err(e) => error!("{}", e), } } } @@ -26,8 +26,13 @@ mod tests { #[test] fn challenge3_xor_cipher() { - let ciphertext = "1b37373331363f78151b7f2b783431333d78397828372d363c78373e783a393b3736".from_hex().unwrap(); + let ciphertext = "1b37373331363f78151b7f2b783431333d78397828372d363c78373e783a393b3736" + .from_hex() + .unwrap(); let (decrypted, _) = break_xor_cipher(ciphertext.as_slice()); - assert_eq!(String::from_utf8(decrypted).unwrap(), "Cooking MC's like a pound of bacon"); + assert_eq!( + String::from_utf8(decrypted).unwrap(), + "Cooking MC's like a pound of bacon" + ); } } diff --git a/set1/challenge4_detect_xor/src/main.rs b/set1/challenge4_detect_xor/src/main.rs index 78c842a..0c2820d 100644 --- a/set1/challenge4_detect_xor/src/main.rs +++ b/set1/challenge4_detect_xor/src/main.rs @@ -2,7 +2,7 @@ use common::break_xor_cipher; use log::error; use rustc_serialize::hex::FromHex; use std::error::Error; -use std::io::{BufRead, stdin}; +use std::io::{stdin, BufRead}; fn detect_xor(input: &mut dyn BufRead) -> Result> { let mut maxscore = 0; @@ -24,21 +24,24 @@ fn main() { match detect_xor(&mut stdin().lock()) { Ok(s) => println!("{}", s), - Err(e) => error!("{}", e) + Err(e) => error!("{}", e), } } #[cfg(test)] mod tests { + use super::*; use std::fs::File; use std::io::BufReader; use std::path::Path; - use super::*; #[test] fn challenge4_detect_xor() { let cargo_manifest_dir = Path::new(env!("CARGO_MANIFEST_DIR")); let testinput = File::open(cargo_manifest_dir.join("4.txt")).unwrap(); - assert_eq!(detect_xor(&mut BufReader::new(testinput)).unwrap(), "Now that the party is jumping\n"); + assert_eq!( + detect_xor(&mut BufReader::new(testinput)).unwrap(), + "Now that the party is jumping\n" + ); } } diff --git a/set1/challenge5_repeating_xor/src/main.rs b/set1/challenge5_repeating_xor/src/main.rs index 565d995..c9e6d7c 100644 --- a/set1/challenge5_repeating_xor/src/main.rs +++ b/set1/challenge5_repeating_xor/src/main.rs @@ -1,6 +1,6 @@ use common::repeating_xor_cipher; use rustc_serialize::hex::ToHex; -use std::io::{BufRead, stdin}; +use std::io::{stdin, BufRead}; fn main() { env_logger::init(); @@ -17,7 +17,9 @@ mod tests { #[test] fn challenge5_repeating_xor() { - let plaintext = "Burning 'em, if you ain't quick and nimble\nI go crazy when I hear a cymbal".as_bytes(); + let plaintext = + "Burning 'em, if you ain't quick and nimble\nI go crazy when I hear a cymbal" + .as_bytes(); let ciphertext = repeating_xor_cipher(plaintext, "ICE".as_bytes()); assert_eq!(ciphertext.to_hex(), "0b3637272a2b2e63622c2e69692a23693a2a3c6324202d623d63343c2a26226324272765272a282b2f20430a652e2c652a3124333a653e2b2027630c692b20283165286326302e27282f"); } diff --git a/set1/challenge6_break_repeating_xor/src/main.rs b/set1/challenge6_break_repeating_xor/src/main.rs index 2c95615..de80f47 100644 --- a/set1/challenge6_break_repeating_xor/src/main.rs +++ b/set1/challenge6_break_repeating_xor/src/main.rs @@ -2,7 +2,7 @@ use common::break_repeating_xor_cipher; use log::error; use rustc_serialize::base64::FromBase64; use std::error::Error; -use std::io::{Read, read_to_string, stdin}; +use std::io::{read_to_string, stdin, Read}; fn break_xor(input: &mut dyn Read) -> Result> { let ciphertext = read_to_string(input)?.from_base64()?; @@ -15,23 +15,25 @@ fn main() { match break_xor(&mut stdin().lock()) { Ok(s) => println!("{}", s), - Err(e) => error!("{}", e) + Err(e) => error!("{}", e), } } #[cfg(test)] mod tests { + use super::*; use std::fs::File; use std::io::BufReader; use std::path::Path; - use super::*; #[test] fn challenge6_break_repeating_xor() { let cargo_manifest_dir = Path::new(env!("CARGO_MANIFEST_DIR")); let testinput = File::open(cargo_manifest_dir.join("6.txt")).unwrap(); let decrypted = break_xor(&mut BufReader::new(testinput)).unwrap(); - let plaintext = read_to_string(File::open(cargo_manifest_dir.join("6_plaintext.txt")).unwrap()).unwrap(); + let plaintext = + read_to_string(File::open(cargo_manifest_dir.join("6_plaintext.txt")).unwrap()) + .unwrap(); assert_eq!(decrypted, plaintext); } }