| 
									
										
										
										
											2022-07-30 02:01:40 +08:00
										 |  |  | use crate::config::Config;
 | 
					
						
							|  |  |  | use sodiumoxide::base64;
 | 
					
						
							|  |  |  | use std::sync::{Arc, RwLock};
 | 
					
						
							| 
									
										
										
										
											2022-06-20 10:41:46 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-07-30 02:01:40 +08:00
										 |  |  | lazy_static::lazy_static! {
 | 
					
						
							|  |  |  |     pub static ref TEMPORARY_PASSWORD:Arc<RwLock<String>> = Arc::new(RwLock::new(Config::get_auto_password(temporary_password_length())));
 | 
					
						
							|  |  |  | }
 | 
					
						
							| 
									
										
										
										
											2022-06-20 10:41:46 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-07-30 02:01:40 +08:00
										 |  |  | #[derive(Debug, Clone, Copy, PartialEq, Eq)]
 | 
					
						
							|  |  |  | enum VerificationMethod {
 | 
					
						
							|  |  |  |     OnlyUseTemporaryPassword,
 | 
					
						
							|  |  |  |     OnlyUsePermanentPassword,
 | 
					
						
							|  |  |  |     UseBothPasswords,
 | 
					
						
							|  |  |  | }
 | 
					
						
							| 
									
										
										
										
											2022-06-20 10:41:46 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-11-21 15:29:00 +08:00
										 |  |  | #[derive(Debug, Clone, Copy, PartialEq, Eq)]
 | 
					
						
							|  |  |  | pub enum ApproveMode {
 | 
					
						
							|  |  |  |     Both,
 | 
					
						
							|  |  |  |     Password,
 | 
					
						
							|  |  |  |     Click,
 | 
					
						
							|  |  |  | }
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-07-30 02:01:40 +08:00
										 |  |  | // Should only be called in server
 | 
					
						
							|  |  |  | pub fn update_temporary_password() {
 | 
					
						
							|  |  |  |     *TEMPORARY_PASSWORD.write().unwrap() = Config::get_auto_password(temporary_password_length());
 | 
					
						
							|  |  |  | }
 | 
					
						
							| 
									
										
										
										
											2022-06-20 10:41:46 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-07-30 02:01:40 +08:00
										 |  |  | // Should only be called in server
 | 
					
						
							|  |  |  | pub fn temporary_password() -> String {
 | 
					
						
							|  |  |  |     TEMPORARY_PASSWORD.read().unwrap().clone()
 | 
					
						
							|  |  |  | }
 | 
					
						
							| 
									
										
										
										
											2022-06-20 10:41:46 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-07-30 02:01:40 +08:00
										 |  |  | fn verification_method() -> VerificationMethod {
 | 
					
						
							|  |  |  |     let method = Config::get_option("verification-method");
 | 
					
						
							|  |  |  |     if method == "use-temporary-password" {
 | 
					
						
							|  |  |  |         VerificationMethod::OnlyUseTemporaryPassword
 | 
					
						
							|  |  |  |     } else if method == "use-permanent-password" {
 | 
					
						
							|  |  |  |         VerificationMethod::OnlyUsePermanentPassword
 | 
					
						
							|  |  |  |     } else {
 | 
					
						
							|  |  |  |         VerificationMethod::UseBothPasswords // default
 | 
					
						
							| 
									
										
										
										
											2022-06-20 10:41:46 +08:00
										 |  |  |     }
 | 
					
						
							| 
									
										
										
										
											2022-07-30 02:01:40 +08:00
										 |  |  | }
 | 
					
						
							| 
									
										
										
										
											2022-06-20 10:41:46 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-07-30 02:01:40 +08:00
										 |  |  | pub fn temporary_password_length() -> usize {
 | 
					
						
							|  |  |  |     let length = Config::get_option("temporary-password-length");
 | 
					
						
							|  |  |  |     if length == "8" {
 | 
					
						
							|  |  |  |         8
 | 
					
						
							|  |  |  |     } else if length == "10" {
 | 
					
						
							|  |  |  |         10
 | 
					
						
							|  |  |  |     } else {
 | 
					
						
							|  |  |  |         6 // default
 | 
					
						
							| 
									
										
										
										
											2022-06-20 10:41:46 +08:00
										 |  |  |     }
 | 
					
						
							| 
									
										
										
										
											2022-07-30 02:01:40 +08:00
										 |  |  | }
 | 
					
						
							| 
									
										
										
										
											2022-06-20 10:41:46 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-07-30 02:01:40 +08:00
										 |  |  | pub fn temporary_enabled() -> bool {
 | 
					
						
							|  |  |  |     verification_method() != VerificationMethod::OnlyUsePermanentPassword
 | 
					
						
							|  |  |  | }
 | 
					
						
							| 
									
										
										
										
											2022-06-20 10:41:46 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-07-30 02:01:40 +08:00
										 |  |  | pub fn permanent_enabled() -> bool {
 | 
					
						
							|  |  |  |     verification_method() != VerificationMethod::OnlyUseTemporaryPassword
 | 
					
						
							| 
									
										
										
										
											2022-06-20 10:41:46 +08:00
										 |  |  | }
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-07-30 02:01:40 +08:00
										 |  |  | pub fn has_valid_password() -> bool {
 | 
					
						
							|  |  |  |     temporary_enabled() && !temporary_password().is_empty()
 | 
					
						
							|  |  |  |         || permanent_enabled() && !Config::get_permanent_password().is_empty()
 | 
					
						
							|  |  |  | }
 | 
					
						
							| 
									
										
										
										
											2022-06-20 10:41:46 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-11-21 15:29:00 +08:00
										 |  |  | pub fn approve_mode() -> ApproveMode {
 | 
					
						
							|  |  |  |     let mode = Config::get_option("approve-mode");
 | 
					
						
							|  |  |  |     if mode == "password" {
 | 
					
						
							|  |  |  |         ApproveMode::Password
 | 
					
						
							|  |  |  |     } else if mode == "click" {
 | 
					
						
							|  |  |  |         ApproveMode::Click
 | 
					
						
							|  |  |  |     } else {
 | 
					
						
							|  |  |  |         ApproveMode::Both
 | 
					
						
							|  |  |  |     }
 | 
					
						
							|  |  |  | }
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-11-23 09:41:05 +08:00
										 |  |  | pub fn hide_cm() -> bool {
 | 
					
						
							|  |  |  |     approve_mode() == ApproveMode::Password
 | 
					
						
							|  |  |  |         && verification_method() == VerificationMethod::OnlyUsePermanentPassword
 | 
					
						
							| 
									
										
										
										
											2024-06-10 00:11:59 +08:00
										 |  |  |         && crate::config::option2bool("allow-hide-cm", &Config::get_option("allow-hide-cm"))
 | 
					
						
							| 
									
										
										
										
											2022-11-23 09:41:05 +08:00
										 |  |  | }
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-07-30 02:01:40 +08:00
										 |  |  | const VERSION_LEN: usize = 2;
 | 
					
						
							| 
									
										
										
										
											2022-06-20 10:41:46 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-08-02 22:25:54 +08:00
										 |  |  | pub fn encrypt_str_or_original(s: &str, version: &str, max_len: usize) -> String {
 | 
					
						
							| 
									
										
										
										
											2022-07-30 02:01:40 +08:00
										 |  |  |     if decrypt_str_or_original(s, version).1 {
 | 
					
						
							|  |  |  |         log::error!("Duplicate encryption!");
 | 
					
						
							|  |  |  |         return s.to_owned();
 | 
					
						
							|  |  |  |     }
 | 
					
						
							| 
									
										
										
										
											2023-08-19 20:44:54 +08:00
										 |  |  |     if s.bytes().len() > max_len {
 | 
					
						
							|  |  |  |         return String::default();
 | 
					
						
							|  |  |  |     }
 | 
					
						
							| 
									
										
										
										
											2022-07-30 02:01:40 +08:00
										 |  |  |     if version == "00" {
 | 
					
						
							| 
									
										
										
										
											2023-08-02 22:25:54 +08:00
										 |  |  |         if let Ok(s) = encrypt(s.as_bytes(), max_len) {
 | 
					
						
							| 
									
										
										
										
											2022-07-30 02:01:40 +08:00
										 |  |  |             return version.to_owned() + &s;
 | 
					
						
							| 
									
										
										
										
											2022-06-20 10:41:46 +08:00
										 |  |  |         }
 | 
					
						
							|  |  |  |     }
 | 
					
						
							| 
									
										
										
										
											2022-07-30 02:01:40 +08:00
										 |  |  |     s.to_owned()
 | 
					
						
							|  |  |  | }
 | 
					
						
							| 
									
										
										
										
											2022-06-20 10:41:46 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-07-30 02:01:40 +08:00
										 |  |  | // String: password
 | 
					
						
							|  |  |  | // bool: whether decryption is successful
 | 
					
						
							|  |  |  | // bool: whether should store to re-encrypt when load
 | 
					
						
							| 
									
										
										
										
											2023-08-27 11:36:01 +08:00
										 |  |  | // note: s.len() return length in bytes, s.chars().count() return char count
 | 
					
						
							|  |  |  | //       &[..2] return the left 2 bytes, s.chars().take(2) return the left 2 chars
 | 
					
						
							| 
									
										
										
										
											2022-07-30 02:01:40 +08:00
										 |  |  | pub fn decrypt_str_or_original(s: &str, current_version: &str) -> (String, bool, bool) {
 | 
					
						
							|  |  |  |     if s.len() > VERSION_LEN {
 | 
					
						
							| 
									
										
										
										
											2023-08-27 11:36:01 +08:00
										 |  |  |         if s.starts_with("00") {
 | 
					
						
							| 
									
										
										
										
											2023-01-27 11:42:08 +08:00
										 |  |  |             if let Ok(v) = decrypt(s[VERSION_LEN..].as_bytes()) {
 | 
					
						
							| 
									
										
										
										
											2022-07-30 02:01:40 +08:00
										 |  |  |                 return (
 | 
					
						
							|  |  |  |                     String::from_utf8_lossy(&v).to_string(),
 | 
					
						
							|  |  |  |                     true,
 | 
					
						
							| 
									
										
										
										
											2023-08-27 11:36:01 +08:00
										 |  |  |                     "00" != current_version,
 | 
					
						
							| 
									
										
										
										
											2022-07-30 02:01:40 +08:00
										 |  |  |                 );
 | 
					
						
							| 
									
										
										
										
											2022-06-20 10:41:46 +08:00
										 |  |  |             }
 | 
					
						
							|  |  |  |         }
 | 
					
						
							|  |  |  |     }
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-07-30 02:01:40 +08:00
										 |  |  |     (s.to_owned(), false, !s.is_empty())
 | 
					
						
							|  |  |  | }
 | 
					
						
							| 
									
										
										
										
											2022-06-20 10:41:46 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-08-02 22:25:54 +08:00
										 |  |  | pub fn encrypt_vec_or_original(v: &[u8], version: &str, max_len: usize) -> Vec<u8> {
 | 
					
						
							| 
									
										
										
										
											2022-07-30 02:01:40 +08:00
										 |  |  |     if decrypt_vec_or_original(v, version).1 {
 | 
					
						
							|  |  |  |         log::error!("Duplicate encryption!");
 | 
					
						
							|  |  |  |         return v.to_owned();
 | 
					
						
							| 
									
										
										
										
											2022-06-20 10:41:46 +08:00
										 |  |  |     }
 | 
					
						
							| 
									
										
										
										
											2023-08-19 20:44:54 +08:00
										 |  |  |     if v.len() > max_len {
 | 
					
						
							|  |  |  |         return vec![];
 | 
					
						
							|  |  |  |     }
 | 
					
						
							| 
									
										
										
										
											2022-07-30 02:01:40 +08:00
										 |  |  |     if version == "00" {
 | 
					
						
							| 
									
										
										
										
											2023-08-02 22:25:54 +08:00
										 |  |  |         if let Ok(s) = encrypt(v, max_len) {
 | 
					
						
							| 
									
										
										
										
											2022-07-30 02:01:40 +08:00
										 |  |  |             let mut version = version.to_owned().into_bytes();
 | 
					
						
							|  |  |  |             version.append(&mut s.into_bytes());
 | 
					
						
							|  |  |  |             return version;
 | 
					
						
							| 
									
										
										
										
											2022-06-20 10:41:46 +08:00
										 |  |  |         }
 | 
					
						
							|  |  |  |     }
 | 
					
						
							| 
									
										
										
										
											2022-07-30 02:01:40 +08:00
										 |  |  |     v.to_owned()
 | 
					
						
							|  |  |  | }
 | 
					
						
							| 
									
										
										
										
											2022-06-20 10:41:46 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-07-30 07:09:31 +08:00
										 |  |  | // Vec<u8>: password
 | 
					
						
							| 
									
										
										
										
											2022-07-30 02:01:40 +08:00
										 |  |  | // bool: whether decryption is successful
 | 
					
						
							|  |  |  | // bool: whether should store to re-encrypt when load
 | 
					
						
							|  |  |  | pub fn decrypt_vec_or_original(v: &[u8], current_version: &str) -> (Vec<u8>, bool, bool) {
 | 
					
						
							|  |  |  |     if v.len() > VERSION_LEN {
 | 
					
						
							|  |  |  |         let version = String::from_utf8_lossy(&v[..VERSION_LEN]);
 | 
					
						
							|  |  |  |         if version == "00" {
 | 
					
						
							|  |  |  |             if let Ok(v) = decrypt(&v[VERSION_LEN..]) {
 | 
					
						
							|  |  |  |                 return (v, true, version != current_version);
 | 
					
						
							|  |  |  |             }
 | 
					
						
							| 
									
										
										
										
											2022-06-20 10:41:46 +08:00
										 |  |  |         }
 | 
					
						
							|  |  |  |     }
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-07-30 02:01:40 +08:00
										 |  |  |     (v.to_owned(), false, !v.is_empty())
 | 
					
						
							|  |  |  | }
 | 
					
						
							| 
									
										
										
										
											2022-06-20 10:41:46 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-08-02 22:25:54 +08:00
										 |  |  | fn encrypt(v: &[u8], max_len: usize) -> Result<String, ()> {
 | 
					
						
							|  |  |  |     if !v.is_empty() && v.len() <= max_len {
 | 
					
						
							| 
									
										
										
										
											2022-07-30 02:01:40 +08:00
										 |  |  |         symmetric_crypt(v, true).map(|v| base64::encode(v, base64::Variant::Original))
 | 
					
						
							|  |  |  |     } else {
 | 
					
						
							|  |  |  |         Err(())
 | 
					
						
							| 
									
										
										
										
											2022-06-20 10:41:46 +08:00
										 |  |  |     }
 | 
					
						
							| 
									
										
										
										
											2022-07-30 02:01:40 +08:00
										 |  |  | }
 | 
					
						
							| 
									
										
										
										
											2022-06-20 10:41:46 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-07-30 02:01:40 +08:00
										 |  |  | fn decrypt(v: &[u8]) -> Result<Vec<u8>, ()> {
 | 
					
						
							| 
									
										
										
										
											2023-01-27 11:42:08 +08:00
										 |  |  |     if !v.is_empty() {
 | 
					
						
							| 
									
										
										
										
											2022-07-30 02:01:40 +08:00
										 |  |  |         base64::decode(v, base64::Variant::Original).and_then(|v| symmetric_crypt(&v, false))
 | 
					
						
							|  |  |  |     } else {
 | 
					
						
							|  |  |  |         Err(())
 | 
					
						
							| 
									
										
										
										
											2022-06-20 10:41:46 +08:00
										 |  |  |     }
 | 
					
						
							|  |  |  | }
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-08-04 15:32:09 +08:00
										 |  |  | pub fn symmetric_crypt(data: &[u8], encrypt: bool) -> Result<Vec<u8>, ()> {
 | 
					
						
							| 
									
										
										
										
											2022-06-20 10:41:46 +08:00
										 |  |  |     use sodiumoxide::crypto::secretbox;
 | 
					
						
							|  |  |  |     use std::convert::TryInto;
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     let mut keybuf = crate::get_uuid();
 | 
					
						
							|  |  |  |     keybuf.resize(secretbox::KEYBYTES, 0);
 | 
					
						
							|  |  |  |     let key = secretbox::Key(keybuf.try_into().map_err(|_| ())?);
 | 
					
						
							|  |  |  |     let nonce = secretbox::Nonce([0; secretbox::NONCEBYTES]);
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if encrypt {
 | 
					
						
							|  |  |  |         Ok(secretbox::seal(data, &nonce, &key))
 | 
					
						
							|  |  |  |     } else {
 | 
					
						
							|  |  |  |         secretbox::open(data, &nonce, &key)
 | 
					
						
							|  |  |  |     }
 | 
					
						
							|  |  |  | }
 | 
					
						
							| 
									
										
										
										
											2022-07-30 02:01:40 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | mod test {
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     #[test]
 | 
					
						
							|  |  |  |     fn test() {
 | 
					
						
							|  |  |  |         use super::*;
 | 
					
						
							| 
									
										
										
										
											2023-08-02 22:25:54 +08:00
										 |  |  |         use rand::{thread_rng, Rng};
 | 
					
						
							|  |  |  |         use std::time::Instant;
 | 
					
						
							| 
									
										
										
										
											2022-07-30 02:01:40 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |         let version = "00";
 | 
					
						
							| 
									
										
										
										
											2023-08-02 22:25:54 +08:00
										 |  |  |         let max_len = 128;
 | 
					
						
							| 
									
										
										
										
											2022-07-30 02:01:40 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |         println!("test str");
 | 
					
						
							| 
									
										
										
										
											2023-08-27 11:36:01 +08:00
										 |  |  |         let data = "1ü1111";
 | 
					
						
							| 
									
										
										
										
											2023-08-02 22:25:54 +08:00
										 |  |  |         let encrypted = encrypt_str_or_original(data, version, max_len);
 | 
					
						
							| 
									
										
										
										
											2022-07-30 02:01:40 +08:00
										 |  |  |         let (decrypted, succ, store) = decrypt_str_or_original(&encrypted, version);
 | 
					
						
							| 
									
										
										
										
											2023-02-08 17:26:44 +08:00
										 |  |  |         println!("data: {data}");
 | 
					
						
							|  |  |  |         println!("encrypted: {encrypted}");
 | 
					
						
							|  |  |  |         println!("decrypted: {decrypted}");
 | 
					
						
							| 
									
										
										
										
											2022-07-30 02:01:40 +08:00
										 |  |  |         assert_eq!(data, decrypted);
 | 
					
						
							|  |  |  |         assert_eq!(version, &encrypted[..2]);
 | 
					
						
							| 
									
										
										
										
											2023-02-08 17:26:44 +08:00
										 |  |  |         assert!(succ);
 | 
					
						
							|  |  |  |         assert!(!store);
 | 
					
						
							| 
									
										
										
										
											2022-07-30 02:01:40 +08:00
										 |  |  |         let (_, _, store) = decrypt_str_or_original(&encrypted, "99");
 | 
					
						
							| 
									
										
										
										
											2023-02-08 17:26:44 +08:00
										 |  |  |         assert!(store);
 | 
					
						
							|  |  |  |         assert!(!decrypt_str_or_original(&decrypted, version).1);
 | 
					
						
							| 
									
										
										
										
											2023-08-02 22:25:54 +08:00
										 |  |  |         assert_eq!(
 | 
					
						
							|  |  |  |             encrypt_str_or_original(&encrypted, version, max_len),
 | 
					
						
							|  |  |  |             encrypted
 | 
					
						
							|  |  |  |         );
 | 
					
						
							| 
									
										
										
										
											2022-07-30 02:01:40 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |         println!("test vec");
 | 
					
						
							| 
									
										
										
										
											2023-08-27 11:36:01 +08:00
										 |  |  |         let data: Vec<u8> = "1ü1111".as_bytes().to_vec();
 | 
					
						
							| 
									
										
										
										
											2023-08-02 22:25:54 +08:00
										 |  |  |         let encrypted = encrypt_vec_or_original(&data, version, max_len);
 | 
					
						
							| 
									
										
										
										
											2022-07-30 02:01:40 +08:00
										 |  |  |         let (decrypted, succ, store) = decrypt_vec_or_original(&encrypted, version);
 | 
					
						
							| 
									
										
										
										
											2023-02-08 17:26:44 +08:00
										 |  |  |         println!("data: {data:?}");
 | 
					
						
							|  |  |  |         println!("encrypted: {encrypted:?}");
 | 
					
						
							|  |  |  |         println!("decrypted: {decrypted:?}");
 | 
					
						
							| 
									
										
										
										
											2022-07-30 02:01:40 +08:00
										 |  |  |         assert_eq!(data, decrypted);
 | 
					
						
							|  |  |  |         assert_eq!(version.as_bytes(), &encrypted[..2]);
 | 
					
						
							| 
									
										
										
										
											2023-02-08 17:26:44 +08:00
										 |  |  |         assert!(!store);
 | 
					
						
							|  |  |  |         assert!(succ);
 | 
					
						
							| 
									
										
										
										
											2022-07-30 02:01:40 +08:00
										 |  |  |         let (_, _, store) = decrypt_vec_or_original(&encrypted, "99");
 | 
					
						
							| 
									
										
										
										
											2023-02-08 17:26:44 +08:00
										 |  |  |         assert!(store);
 | 
					
						
							|  |  |  |         assert!(!decrypt_vec_or_original(&decrypted, version).1);
 | 
					
						
							| 
									
										
										
										
											2023-08-02 22:25:54 +08:00
										 |  |  |         assert_eq!(
 | 
					
						
							|  |  |  |             encrypt_vec_or_original(&encrypted, version, max_len),
 | 
					
						
							|  |  |  |             encrypted
 | 
					
						
							|  |  |  |         );
 | 
					
						
							| 
									
										
										
										
											2022-07-30 02:01:40 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |         println!("test original");
 | 
					
						
							|  |  |  |         let data = version.to_string() + "Hello World";
 | 
					
						
							|  |  |  |         let (decrypted, succ, store) = decrypt_str_or_original(&data, version);
 | 
					
						
							|  |  |  |         assert_eq!(data, decrypted);
 | 
					
						
							| 
									
										
										
										
											2023-02-08 17:26:44 +08:00
										 |  |  |         assert!(store);
 | 
					
						
							|  |  |  |         assert!(!succ);
 | 
					
						
							| 
									
										
										
										
											2022-07-30 02:01:40 +08:00
										 |  |  |         let verbytes = version.as_bytes();
 | 
					
						
							| 
									
										
										
										
											2023-02-08 17:26:44 +08:00
										 |  |  |         let data: Vec<u8> = vec![verbytes[0], verbytes[1], 1, 2, 3, 4, 5, 6];
 | 
					
						
							| 
									
										
										
										
											2022-07-30 02:01:40 +08:00
										 |  |  |         let (decrypted, succ, store) = decrypt_vec_or_original(&data, version);
 | 
					
						
							|  |  |  |         assert_eq!(data, decrypted);
 | 
					
						
							| 
									
										
										
										
											2023-02-08 17:26:44 +08:00
										 |  |  |         assert!(store);
 | 
					
						
							|  |  |  |         assert!(!succ);
 | 
					
						
							| 
									
										
										
										
											2022-07-30 02:01:40 +08:00
										 |  |  |         let (_, succ, store) = decrypt_str_or_original("", version);
 | 
					
						
							| 
									
										
										
										
											2023-02-08 17:26:44 +08:00
										 |  |  |         assert!(!store);
 | 
					
						
							|  |  |  |         assert!(!succ);
 | 
					
						
							|  |  |  |         let (_, succ, store) = decrypt_vec_or_original(&[], version);
 | 
					
						
							|  |  |  |         assert!(!store);
 | 
					
						
							|  |  |  |         assert!(!succ);
 | 
					
						
							| 
									
										
										
										
											2023-08-27 11:36:01 +08:00
										 |  |  |         let data = "1ü1111";
 | 
					
						
							|  |  |  |         assert_eq!(decrypt_str_or_original(data, version).0, data);
 | 
					
						
							|  |  |  |         let data: Vec<u8> = "1ü1111".as_bytes().to_vec();
 | 
					
						
							|  |  |  |         assert_eq!(decrypt_vec_or_original(&data, version).0, data);
 | 
					
						
							| 
									
										
										
										
											2023-08-02 22:25:54 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |         println!("test speed");
 | 
					
						
							|  |  |  |         let test_speed = |len: usize, name: &str| {
 | 
					
						
							|  |  |  |             let mut data: Vec<u8> = vec![];
 | 
					
						
							|  |  |  |             let mut rng = thread_rng();
 | 
					
						
							|  |  |  |             for _ in 0..len {
 | 
					
						
							|  |  |  |                 data.push(rng.gen_range(0..255));
 | 
					
						
							|  |  |  |             }
 | 
					
						
							|  |  |  |             let start: Instant = Instant::now();
 | 
					
						
							|  |  |  |             let encrypted = encrypt_vec_or_original(&data, version, len);
 | 
					
						
							|  |  |  |             assert_ne!(data, decrypted);
 | 
					
						
							|  |  |  |             let t1 = start.elapsed();
 | 
					
						
							|  |  |  |             let start = Instant::now();
 | 
					
						
							|  |  |  |             let (decrypted, _, _) = decrypt_vec_or_original(&encrypted, version);
 | 
					
						
							|  |  |  |             let t2 = start.elapsed();
 | 
					
						
							|  |  |  |             assert_eq!(data, decrypted);
 | 
					
						
							|  |  |  |             println!("{name}");
 | 
					
						
							|  |  |  |             println!("encrypt:{:?}, decrypt:{:?}", t1, t2);
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             let start: Instant = Instant::now();
 | 
					
						
							|  |  |  |             let encrypted = base64::encode(&data, base64::Variant::Original);
 | 
					
						
							|  |  |  |             let t1 = start.elapsed();
 | 
					
						
							|  |  |  |             let start = Instant::now();
 | 
					
						
							|  |  |  |             let decrypted = base64::decode(&encrypted, base64::Variant::Original).unwrap();
 | 
					
						
							|  |  |  |             let t2 = start.elapsed();
 | 
					
						
							|  |  |  |             assert_eq!(data, decrypted);
 | 
					
						
							|  |  |  |             println!("base64, encrypt:{:?}, decrypt:{:?}", t1, t2,);
 | 
					
						
							|  |  |  |         };
 | 
					
						
							|  |  |  |         test_speed(128, "128");
 | 
					
						
							|  |  |  |         test_speed(1024, "1k");
 | 
					
						
							|  |  |  |         test_speed(1024 * 1024, "1M");
 | 
					
						
							|  |  |  |         test_speed(10 * 1024 * 1024, "10M");
 | 
					
						
							|  |  |  |         test_speed(100 * 1024 * 1024, "100M");
 | 
					
						
							| 
									
										
										
										
											2022-07-30 02:01:40 +08:00
										 |  |  |     }
 | 
					
						
							|  |  |  | }
 |