random_encrypt 0.1.0

通过计算生成加密key,并且设置生命周期,在不同的生命周期,相同的字符串返回不同的加密结果
Documentation
use std::collections::HashMap;
use chrono::{prelude::*, DateTime, TimeZone, NaiveDateTime, Utc, Duration};

#[derive(Debug)]
pub struct RandomEncrypt {
    /** 转换目标时区:北京/东八区 */
    timezone: i32,
    /** key有效期(单位秒) */
    time_interval: i64,
    options: i32,
    /** key 加密字符串长度 */
    key_length: i32,
    /** 如果跨时区 冗余几秒 */
    second_redundancy: i32,
    /** 当前(北京/东八区时间)时间戳 */
    timestamp: i64,

    key_map: HashMap<String, String>,
    /** 预设加密算法 */
    cipher_algo: (String, String, String, String, String, String),
}

impl RandomEncrypt {
    /// 获取当前时间对应东八区时间戳
    fn timezone_timestamp(&self) -> i64 {
        let l: DateTime<Local> = Local::now();
        let o: i32 = l.offset().local_minus_utc() / 3600;
        let fst: FixedOffset = FixedOffset::east_opt((self.timezone - o) * 60 * 60).unwrap();
        let u: DateTime<Utc> = Utc::now();
        let df: DateTime<FixedOffset> = u.with_timezone(&fst);
        let n: NaiveDateTime = NaiveDateTime::new(df.date_naive(), df.time());
        n.timestamp()
    }

    /// 获取当前时间区间的闭区间 区间长度默认为5秒
    /// 当前时间为 2023-02-22 12:13:11 => 2023-02-22 12:13:15
    fn get_time_group(&mut self) -> i64 {
        (self.timestamp / self.time_interval + (self.timestamp % self.time_interval > 0) as i64) * self.time_interval
    }

    fn get_datetime_from_timestamp(&self, timestamp: i64) -> String {
        let option_native: Option<NaiveDateTime> = NaiveDateTime::from_timestamp_opt(timestamp, 0);
        if let Some(native) = option_native {
            let fst: FixedOffset = FixedOffset::east_opt(8 * 60 * 60).unwrap();
            let datetime: DateTime<FixedOffset> = DateTime::from_utc(native, fst);
            return datetime.format("%Y%m%d%H%M%S").to_string();
        }
        String::new()
    }

    fn key(&mut self, timestamp: i64) -> (String, String) {
        if timestamp > 0 {
            self.timestamp = timestamp;
        } else {
            self.timestamp = self.timezone_timestamp();
        }
        let timestamp_group: i64 = self.get_time_group();
        let datetime: String = self.get_datetime_from_timestamp(timestamp_group);
        let key: String = datetime.chars().into_iter().map(|x| {
            let val = self.key_map.get(x.to_string().as_str());
            match val {
                Some(v) => v,
                None => ""
            }
        }).collect::<Vec<&str>>().join("");
        let index: i32 = (datetime.parse::<i64>().unwrap() % self.key_length as i64) as i32;
        let passphrase: String = format!("{}{}{}", datetime, key, datetime);
        let vi: String = format!("{}{}{}", key, datetime, key);
        (self.get_encrypt_key(passphrase, index), self.get_encrypt_key(vi, index))
    }

    fn get_encrypt_key(&self, key: String, index: i32) -> String {
        let s = format!("{:?}", md5::compute(key)).to_lowercase();
        let end = index + self.key_length;
        s[index as usize..end as usize].to_string()
    }

    pub fn encrypt(&mut self, str: String) -> String {
        let (key, vi) = self.key(0);
        println!("{},{}", key, vi);
        String::new()
    }
    pub fn new() -> Self {
        RandomEncrypt {
            timezone: 9,
            time_interval: 5,
            options: 1,
            key_length: 16,
            second_redundancy: 2,
            timestamp: 0,
            key_map: HashMap::from([
                (String::from("1"), String::from("#")),
                (String::from("2"), String::from("0")),
                (String::from("3"), String::from("*")),
                (String::from("4"), String::from("9")),
                (String::from("5"), String::from("8")),
                (String::from("6"), String::from("7")),
                (String::from("7"), String::from("6")),
                (String::from("8"), String::from("5")),
                (String::from("9"), String::from("4")),
                (String::from("*"), String::from("3")),
                (String::from("0"), String::from("2")),
                (String::from("#"), String::from("1")),
            ]),
            cipher_algo: (
                String::from("AES-128-CBC"),
                String::from("ARIA-128-CTR"),
                String::from("CAMELLIA-128-CBC"),
                String::from("SEED-CBC"),
                String::from("SM4-CBC"),
                String::from("AES-256-CBC-HMAC-SHA256"),
            ),
        }
    }
}