use base64::{Engine as _, engine::general_purpose}; use std::error::Error; fn xor_bytes(buffer: &mut Vec, xor: u8) { for b in buffer { *b = *b ^ xor } } // See: https://stackoverflow.com/questions/41034635/how-do-i-convert-between-string-str-vecu8-and-u8 // for conversion examples (to/from str/String/Vec). pub fn encode(text: &str, xor: u8) -> String { let mut temp = text.as_bytes().to_owned(); xor_bytes(temp.as_mut(), xor); general_purpose::STANDARD.encode(temp) } pub fn decode(text: &str, xor: u8) -> Result> { let mut chars = general_purpose::STANDARD.decode(text)?; xor_bytes(chars.as_mut(), xor); Ok(String::from_utf8(chars)?) } #[cfg(test)] mod tests { use super::*; #[test] fn encode_test() { let t1 = "hello world"; let t2 = encode(t1, 'U' as u8); assert_eq!(t2, "PTA5OTp1IjonOTE="); } #[test] fn encode_utf8_test() { let t1 = "🍺"; let t2 = encode(&t1, 'U' as u8); assert_eq!(t2, "pcrY7w=="); } #[test] fn decode_test() { let t1= "ICYiPCE2PW9vMTA2OjEw"; let t2 = decode(&t1, 'U' as u8); match t2 { Ok(s) => assert_eq!(s, "uswitch::decode"), Err(err) => panic!("{}", err), } } #[test] fn decode_utf8_test() { let t1 = "t9f5"; let t2 = decode(&t1, 'U' as u8); match t2 { Ok(s) => assert_eq!(s, "€"), Err(err) => panic!("{}", err), } } #[test] fn decode_fail_test() { let t1 = "yAyL3WlysPBdTEnPDs+JnWlytjv"; // Invalid base64 let t2 = decode(&t1, 'U' as u8); match t2 { Ok(s) => panic!("Expected failure! Got '{}'", s), Err(_) => () } } #[test] fn decode_fail_utf8_test() { let t1 = "woXChQ=="; // Invalid UTF-8 let t2 = decode(&t1, 'U' as u8); match t2 { Ok(s) => panic!("Expected failure! Got '{}'", s), Err(_) => () } } }