mod basics {
extern crate base64;
use std::u8;
pub fn to_bytes(hex: &String) -> Vec<u8> {
let mut bytes = Vec::new();
for i in 0..(hex.len() / 2) {
let res = u8::from_str_radix(&hex[(2 * i)..(2 * i + 2)], 16);
match res {
Ok(v) => bytes.push(v),
Err(e) => println!("Problem with hex: {}", e),
};
}
return bytes;
}
pub fn to_hex(bytes: Vec<u8>) -> String {
let strs: Vec<String> = bytes.iter().map(|b| format!("{:X}", b)).collect();
strs.join("").to_lowercase()
}
pub fn hex_to_base64(hex: &String) -> String {
let bytes = to_bytes(&hex);
return base64::encode(&bytes);
}
pub fn xor(a: &Vec<u8>, b: &Vec<u8>) -> Vec<u8> {
if a.len() != b.len() {
panic!("Different buffer sizes: {} and {}", a.len(), b.len());
}
let mut result: Vec<u8> = Vec::new();
for (x, y) in a.iter().zip(b.iter()) {
result.push(x ^ y);
}
return result;
}
}
#[cfg(test)]
mod basics_tests {
use super::basics::*;
#[test]
fn hex_to_base64_test() {
let hex = String::from(
"49276d206b696c6c696e6720796f757220627261696e206c696b65206120706f6\
9736f6e6f7573206d757368726f6f6d",
);
let oct = String::from(
"SSdtIGtpbGxpbmcgeW91ciBicmFpbiBsaWtlIGEgcG9pc29ub3VzIG11c2hyb29t",
);
assert_eq!(hex_to_base64(&hex), oct);
}
#[test]
fn xor_test() {
let a = String::from("1c0111001f010100061a024b53535009181c");
let b = String::from("686974207468652062756c6c277320657965");
let solution = String::from("746865206b696420646f6e277420706c6179");
let result = to_hex(xor(&to_bytes(&a), &to_bytes(&b)));
assert_eq!(result, solution);
}
}