use std::string::FromUtf8Error;
pub fn decrypt_string(encrypted: &[u8], key: u8) -> Result<String, FromUtf8Error> {
let decrypted_bytes: Vec<u8> = encrypted.iter().map(|&b| b ^ key).collect();
String::from_utf8(decrypted_bytes)
}
#[macro_export]
macro_rules! sc {
($s:expr, $key:expr) => {{
const fn xor_encrypt_const(input: &str, key: u8) -> [u8; 256] {
const fn xor_encrypt_recursive(input: &[u8], key: u8, i: usize, mut acc: [u8; 256]) -> [u8; 256] {
if i == input.len() {
acc
} else {
acc[i] = input[i] ^ key;
xor_encrypt_recursive(input, key, i + 1, acc)
}
}
xor_encrypt_recursive(input.as_bytes(), key, 0, [0; 256])
}
const ENCRYPTED: [u8; 256] = xor_encrypt_const($s, $key);
decrypt_string(&ENCRYPTED[..$s.len()], $key)
}};
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_sc_macro_success() {
const KEY: u8 = 20;
let decrypted = sc!("Hello, World!", KEY);
assert_eq!(decrypted.unwrap(), "Hello, World!");
}
#[test]
fn test_sc_macro_empty_string() {
const KEY: u8 = 20;
let decrypted = sc!("", KEY);
assert_eq!(decrypted.unwrap(), "");
}
#[test]
fn test_sc_macro_special_characters() {
const KEY: u8 = 20;
let decrypted = sc!("!@#$%^&*()", KEY);
assert_eq!(decrypted.unwrap(), "!@#$%^&*()");
}
}