cryptopals-rust/set1/detect_xor/src/main.rs

49 lines
1.3 KiB
Rust

#[macro_use]
extern crate log;
extern crate env_logger;
extern crate rustc_serialize;
use rustc_serialize::hex::FromHex;
use std::io::{BufRead, stdin};
use std::iter::repeat;
fn score(plaintext: &Vec<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 mut score = 0;
for ch in plaintext.iter() {
if ch >= &97 && ch <= &122 {
score += ranking[(ch - 97) as usize];
}
}
score
}
fn main() {
env_logger::init().unwrap();
let stdin = stdin();
let mut maxscore = 0;
let mut decrypted: Vec<u8> = vec![];
for line in stdin.lock().lines().filter_map(|x| x.ok()) {
match line.from_hex() {
Ok(ciphertext) => {
for key in 0..0xff {
let plaintext: Vec<u8> = ciphertext.iter().zip(repeat(key)).map(|(c, k)| c ^ k).collect();
let s = score(&plaintext);
if s > maxscore {
maxscore = s;
decrypted = plaintext;
}
}
}
Err(e) => error!("{}", e)
}
}
match String::from_utf8(decrypted) {
Ok(s) => println!("{}", s),
Err(e) => error!("{}", e)
}
}