use md5::{Digest, Md5};
use std::time::SystemTime;
pub fn motp(secret: &str, pin: &str, period: u64, digits: usize) -> String {
let seconds = SystemTime::now()
.duration_since(SystemTime::UNIX_EPOCH)
.unwrap()
.as_secs();
get_motp_code(secret, pin, period, digits, seconds)
}
fn get_motp_code(secret: &str, pin: &str, period: u64, digits: usize, seconds: u64) -> String {
let hex_secret = secret;
let counter = seconds / period;
let data = format!("{counter}{hex_secret}{pin}");
let mut md5_hasher = Md5::new();
md5_hasher.update(data.as_bytes());
let code = hex::encode(md5_hasher.finalize());
code.as_str()[0..digits].to_owned()
}
#[cfg(test)]
mod tests {
use super::get_motp_code;
#[test]
fn test_motp() {
let seconds: u64 = 165892298;
assert_eq!(
"e7d8b6".to_string(),
get_motp_code("e3152afee62599c8", "1234", 10, 6, seconds)
);
}
}