use chrono::{Utc, Duration}; use smcrypto::sm2; use base64; pub fn generate_code(email: &str, days: i64, public_key: &str) -> String {
let enc_ctx = sm2::Encrypt::new(public_key);
let now = Utc::now();
let expire_time = now + Duration::days(days);
let data = format!("{}|{}", email, expire_time.to_rfc3339());
let encrypted_data = enc_ctx.encrypt(data.as_bytes());
let encrypted_hex = hex::encode(encrypted_data);
let code = base64::encode(encrypted_hex);
code
}
pub fn decode_code(code: &str, private_key: &str) -> (String, chrono::DateTime<Utc>) {
let dec_ctx = sm2::Decrypt::new(private_key);
let encrypted_hex = base64::decode(code).expect("Decoding base64 failed");
let encrypted_data = hex::decode(String::from_utf8(encrypted_hex).expect("Invalid UTF-8")).expect("Decoding hex failed");
let decrypted_data = dec_ctx.decrypt(&encrypted_data);
let data = String::from_utf8(decrypted_data).expect("Invalid UTF-8");
let parts: Vec<&str> = data.split('|').collect();
if parts.len() == 2 {
let email = parts[0].to_string();
let expire_time = chrono::DateTime::parse_from_rfc3339(parts[1])
.expect("Invalid expire time format")
.with_timezone(&Utc); (email, expire_time)
} else {
panic!("Invalid code format");
}
}