use std::collections::VecDeque; use openssl::bn::BigNum; use crate::PK_LENGTH; /// The allowed character set in a product key. pub const P_KEY_CHARSET: [char; 24] = [ 'B', 'C', 'D', 'F', 'G', 'H', 'J', 'K', 'M', 'P', 'Q', 'R', 'T', 'V', 'W', 'X', 'Y', '2', '3', '4', '6', '7', '8', '9', ]; pub fn base24_decode(cd_key: &str) -> Vec { let p_decoded_key: Vec = cd_key .chars() .filter_map(|c| P_KEY_CHARSET.iter().position(|&x| x == c).map(|i| i as u8)) .collect(); let mut y = BigNum::from_u32(0).unwrap(); for i in p_decoded_key { y.mul_word((PK_LENGTH - 1) as u32).unwrap(); y.add_word(i.into()).unwrap(); } y.to_vec() } pub fn base24_encode(byte_seq: &[u8]) -> String { let mut z = BigNum::from_slice(byte_seq).unwrap(); let mut out: VecDeque = VecDeque::new(); (0..=24).for_each(|_| out.push_front(P_KEY_CHARSET[z.div_word(24).unwrap() as usize])); out.iter().collect() } #[cfg(test)] mod tests { #[test] fn test_base24() { let input = "JTW3TJ7PFJ7V9CCMX84V9PFT8"; let unbase24 = super::base24_decode(input); println!("{:?}", unbase24); let base24 = super::base24_encode(&unbase24); println!("{}", base24); assert_eq!(input, base24); } }