Spaces:
Sleeping
Sleeping
| use base64::{engine::general_purpose::STANDARD as BASE64, Engine as _}; | |
| use rand::Rng; | |
| use sha2::{Digest, Sha256}; | |
| pub fn generate_hash() -> String { | |
| let random_bytes = rand::thread_rng().gen::<[u8; 32]>(); | |
| let mut hasher = Sha256::new(); | |
| hasher.update(random_bytes); | |
| hex::encode(hasher.finalize()) | |
| } | |
| fn obfuscate_bytes(bytes: &mut [u8]) { | |
| let mut prev: u8 = 165; | |
| for (idx, byte) in bytes.iter_mut().enumerate() { | |
| let old_value = *byte; | |
| *byte = (old_value ^ prev).wrapping_add((idx % 256) as u8); | |
| prev = *byte; | |
| } | |
| } | |
| fn deobfuscate_bytes(bytes: &mut [u8]) { | |
| let mut prev: u8 = 165; | |
| for (idx, byte) in bytes.iter_mut().enumerate() { | |
| let temp = *byte; | |
| *byte = (*byte).wrapping_sub((idx % 256) as u8) ^ prev; | |
| prev = temp; | |
| } | |
| } | |
| pub fn generate_timestamp_header() -> String { | |
| let timestamp = std::time::SystemTime::now() | |
| .duration_since(std::time::UNIX_EPOCH) | |
| .unwrap() | |
| .as_secs() | |
| / 1_000; | |
| let mut timestamp_bytes = vec![ | |
| ((timestamp >> 8) & 0xFF) as u8, | |
| (0xFF & timestamp) as u8, | |
| ((timestamp >> 24) & 0xFF) as u8, | |
| ((timestamp >> 16) & 0xFF) as u8, | |
| ((timestamp >> 8) & 0xFF) as u8, | |
| (0xFF & timestamp) as u8, | |
| ]; | |
| obfuscate_bytes(&mut timestamp_bytes); | |
| BASE64.encode(×tamp_bytes) | |
| } | |
| fn generate_checksum(device_id: &str, mac_addr: Option<&str>) -> String { | |
| let encoded = generate_timestamp_header(); | |
| match mac_addr { | |
| Some(mac) => format!("{}{}/{}", encoded, device_id, mac), | |
| None => format!("{}{}", encoded, device_id), | |
| } | |
| } | |
| pub fn generate_checksum_with_default() -> String { | |
| generate_checksum(&generate_hash(), Some(&generate_hash())) | |
| } | |
| pub fn generate_checksum_with_repair(checksum: &str) -> String { | |
| // 预校验:检查字符串是否为空或只包含合法的Base64字符和'/' | |
| if checksum.is_empty() | |
| || !checksum | |
| .chars() | |
| .all(|c| (c.is_ascii_alphanumeric() || c == '/' || c == '+' || c == '=')) | |
| { | |
| return generate_checksum_with_default(); | |
| } | |
| // 尝试修复时间戳头的函数 | |
| fn try_fix_timestamp(timestamp_base64: &str) -> Option<String> { | |
| if let Ok(timestamp_bytes) = BASE64.decode(timestamp_base64) { | |
| if timestamp_bytes.len() == 6 { | |
| let mut fixed_bytes = timestamp_bytes.clone(); | |
| deobfuscate_bytes(&mut fixed_bytes); | |
| // 检查前3位是否为0 | |
| if fixed_bytes[0..3].iter().all(|&x| x == 0) { | |
| // 从后四位构建时间戳 | |
| let timestamp = ((fixed_bytes[2] as u64) << 24) | |
| | ((fixed_bytes[3] as u64) << 16) | |
| | ((fixed_bytes[4] as u64) << 8) | |
| | (fixed_bytes[5] as u64); | |
| let current_timestamp = std::time::SystemTime::now() | |
| .duration_since(std::time::UNIX_EPOCH) | |
| .unwrap() | |
| .as_secs() | |
| / 1_000; | |
| if timestamp <= current_timestamp { | |
| // 修复时间戳字节 | |
| fixed_bytes[0] = fixed_bytes[4]; | |
| fixed_bytes[1] = fixed_bytes[5]; | |
| obfuscate_bytes(&mut fixed_bytes); | |
| return Some(BASE64.encode(&fixed_bytes)); | |
| } | |
| } | |
| } | |
| } | |
| None | |
| } | |
| if checksum.len() == 8 { | |
| // 尝试修复时间戳头 | |
| if let Some(fixed_timestamp) = try_fix_timestamp(checksum) { | |
| return format!("{}{}/{}", fixed_timestamp, generate_hash(), generate_hash()); | |
| } | |
| // 验证原始时间戳 | |
| if let Some(timestamp) = extract_time_ks(checksum) { | |
| let current_timestamp = std::time::SystemTime::now() | |
| .duration_since(std::time::UNIX_EPOCH) | |
| .unwrap() | |
| .as_secs() | |
| / 1_000; | |
| if timestamp <= current_timestamp { | |
| return format!("{}{}/{}", checksum, generate_hash(), generate_hash()); | |
| } | |
| } | |
| } else if checksum.len() > 8 { | |
| // 处理可能包含hash的情况 | |
| let parts: Vec<&str> = checksum.split('/').collect(); | |
| match parts.len() { | |
| 1 => { | |
| let timestamp_base64 = &checksum[..8]; | |
| let device_id = &checksum[8..]; | |
| if is_valid_hash(device_id) { | |
| // 先尝试修复时间戳 | |
| if let Some(fixed_timestamp) = try_fix_timestamp(timestamp_base64) { | |
| return format!("{}{}/{}", fixed_timestamp, device_id, generate_hash()); | |
| } | |
| // 验证原始时间戳 | |
| if let Some(timestamp) = extract_time_ks(timestamp_base64) { | |
| let current_timestamp = std::time::SystemTime::now() | |
| .duration_since(std::time::UNIX_EPOCH) | |
| .unwrap() | |
| .as_secs() | |
| / 1_000; | |
| if timestamp <= current_timestamp { | |
| return format!( | |
| "{}{}/{}", | |
| generate_timestamp_header(), | |
| device_id, | |
| generate_hash() | |
| ); | |
| } | |
| } | |
| } | |
| } | |
| 2 => { | |
| let first_part = parts[0]; | |
| let mac_hash = parts[1]; | |
| if is_valid_hash(mac_hash) && first_part.len() == mac_hash.len() + 8 { | |
| let timestamp_base64 = &first_part[..8]; | |
| let device_id = &first_part[8..]; | |
| if is_valid_hash(device_id) { | |
| // 先尝试修复时间戳 | |
| if let Some(fixed_timestamp) = try_fix_timestamp(timestamp_base64) { | |
| return format!("{}{}/{}", fixed_timestamp, device_id, mac_hash); | |
| } | |
| // 验证原始时间戳 | |
| if let Some(timestamp) = extract_time_ks(timestamp_base64) { | |
| let current_timestamp = std::time::SystemTime::now() | |
| .duration_since(std::time::UNIX_EPOCH) | |
| .unwrap() | |
| .as_secs() | |
| / 1_000; | |
| if timestamp <= current_timestamp { | |
| return format!( | |
| "{}{}/{}", | |
| generate_timestamp_header(), | |
| device_id, | |
| mac_hash | |
| ); | |
| } | |
| } | |
| } | |
| } | |
| } | |
| _ => {} | |
| } | |
| } | |
| // 如果所有修复尝试都失败,返回默认值 | |
| generate_checksum_with_default() | |
| } | |
| pub fn extract_time_ks(timestamp_base64: &str) -> Option<u64> { | |
| let mut timestamp_bytes = BASE64.decode(timestamp_base64).ok()?; | |
| if timestamp_bytes.len() != 6 { | |
| return None; | |
| } | |
| deobfuscate_bytes(&mut timestamp_bytes); | |
| if timestamp_bytes[0] != timestamp_bytes[4] || timestamp_bytes[1] != timestamp_bytes[5] { | |
| return None; | |
| } | |
| // 使用后四位还原 timestamp | |
| Some( | |
| ((timestamp_bytes[2] as u64) << 24) | |
| | ((timestamp_bytes[3] as u64) << 16) | |
| | ((timestamp_bytes[4] as u64) << 8) | |
| | (timestamp_bytes[5] as u64), | |
| ) | |
| } | |
| pub fn validate_checksum(checksum: &str) -> bool { | |
| // 预校验:检查字符串是否为空或只包含合法的Base64字符和'/' | |
| if checksum.is_empty() | |
| || !checksum | |
| .chars() | |
| .all(|c| (c.is_ascii_alphanumeric() || c == '/' || c == '+' || c == '=')) | |
| { | |
| return false; | |
| } | |
| // 首先检查是否包含基本的 base64 编码部分和 hash 格式的 device_id | |
| let parts: Vec<&str> = checksum.split('/').collect(); | |
| match parts.len() { | |
| // 没有 MAC 地址的情况 | |
| 1 => { | |
| if checksum.len() < 72 { | |
| // 8 + 64 = 72 | |
| return false; | |
| } | |
| // 解码前8个字符的base64时间戳 | |
| let timestamp_base64 = &checksum[..8]; | |
| let timestamp = match extract_time_ks(timestamp_base64) { | |
| Some(ts) => ts, | |
| None => return false, | |
| }; | |
| let current_timestamp = std::time::SystemTime::now() | |
| .duration_since(std::time::UNIX_EPOCH) | |
| .unwrap() | |
| .as_secs() | |
| / 1_000; | |
| if current_timestamp < timestamp { | |
| return false; | |
| } | |
| // 验证 device_id hash 部分 | |
| is_valid_hash(&checksum[8..]) | |
| } | |
| // 包含 MAC hash 的情况 | |
| 2 => { | |
| let first_part = parts[0]; | |
| let mac_hash = parts[1]; | |
| // MAC hash 必须是64字符的十六进制 | |
| if !is_valid_hash(mac_hash) { | |
| return false; | |
| } | |
| // 检查第一部分比MAC hash多8个字符 | |
| if first_part.len() != mac_hash.len() + 8 { | |
| return false; | |
| } | |
| // 递归验证第一部分 | |
| validate_checksum(first_part) | |
| } | |
| _ => false, | |
| } | |
| } | |
| fn is_valid_hash(hash: &str) -> bool { | |
| if hash.len() < 64 { | |
| return false; | |
| } | |
| // 检查是否都是有效的十六进制字符 | |
| hash.chars().all(|c| c.is_ascii_hexdigit()) | |
| } | |