004df79e66
Signed-off-by: Catty Steve <4795515+Catty2014@user.noreply.gitee.com>
165 lines
5.8 KiB
Rust
165 lines
5.8 KiB
Rust
// device_id_generator.rs
|
|
use serde::Serialize;
|
|
mod device_info;
|
|
use crate::device_info::{DeviceInfo, DeviceInfoCollector};
|
|
use sha2::{Sha256, Digest};
|
|
use std::collections::HashMap;
|
|
|
|
pub struct DeviceIdGenerator;
|
|
|
|
impl DeviceIdGenerator {
|
|
/// 生成设备ID - 主要方法
|
|
pub fn generate_device_id() -> Result<String, ()> {
|
|
let device_info = DeviceInfoCollector::collect_device_info()?;
|
|
Self::calculate_device_hash(&device_info)
|
|
}
|
|
|
|
/// 生成设备ID - 带自定义元数据
|
|
pub fn generate_device_id_with_metadata(
|
|
additional_metadata: &HashMap<String, String>
|
|
) -> Result<String, ()> {
|
|
let mut device_info = DeviceInfoCollector::collect_device_info()?;
|
|
|
|
// 合并额外的元数据
|
|
for (key, value) in additional_metadata {
|
|
device_info.system_metadata.insert(key.clone(), value.clone());
|
|
}
|
|
|
|
Self::calculate_device_hash(&device_info)
|
|
}
|
|
|
|
/// 计算设备信息的SHA256哈希
|
|
fn calculate_device_hash(device_info: &DeviceInfo) -> Result<String, ()> {
|
|
let data_string = Self::serialize_device_info(device_info);
|
|
let hash = Self::calculate_sha256(&data_string);
|
|
|
|
Ok(hash)
|
|
}
|
|
|
|
/// 将设备信息序列化为字符串用于哈希计算
|
|
fn serialize_device_info(device_info: &DeviceInfo) -> String {
|
|
// 按照固定顺序拼接关键信息,确保一致性
|
|
let mut components = Vec::new();
|
|
|
|
// 基础标识信息
|
|
components.push(format!("username:{}", device_info.username));
|
|
components.push(format!("hostname:{}", device_info.hostname));
|
|
components.push(format!("os_name:{}", device_info.os_name));
|
|
components.push(format!("os_version:{}", device_info.os_version));
|
|
components.push(format!("architecture:{}", device_info.architecture));
|
|
|
|
// CPU标识信息 - 这些是相对稳定的
|
|
components.push(format!("cpu_vendor:{}", device_info.cpu_info.vendor_id));
|
|
components.push(format!("cpu_brand:{}", device_info.cpu_info.brand));
|
|
components.push(format!("cpu_family:{}", device_info.cpu_info.family));
|
|
components.push(format!("cpu_model:{}", device_info.cpu_info.model));
|
|
components.push(format!("cpu_stepping:{}", device_info.cpu_info.stepping));
|
|
|
|
// 按字母顺序添加CPU特性,确保一致性
|
|
let mut sorted_features = device_info.cpu_info.features.clone();
|
|
sorted_features.sort();
|
|
components.push(format!("cpu_features:{}", sorted_features.join(",")));
|
|
|
|
if let Some(cache_size) = device_info.cpu_info.cache_size {
|
|
components.push(format!("cpu_cache:{}", cache_size));
|
|
}
|
|
|
|
// 按字母顺序添加系统元数据,确保一致性
|
|
let mut sorted_metadata: Vec<_> = device_info.system_metadata.iter().collect();
|
|
sorted_metadata.sort_by_key(|(k, _)| *k);
|
|
|
|
for (key, value) in sorted_metadata {
|
|
components.push(format!("{}:{}", key, value));
|
|
}
|
|
|
|
components.join("|")
|
|
}
|
|
|
|
/// 计算SHA256哈希值
|
|
fn calculate_sha256(data: &str) -> String {
|
|
let mut hasher = Sha256::new();
|
|
hasher.update(data.as_bytes());
|
|
let result = hasher.finalize();
|
|
|
|
// 转换为十六进制字符串
|
|
result.iter()
|
|
.map(|byte| format!("{:02x}", byte))
|
|
.collect()
|
|
}
|
|
|
|
/// 验证设备ID是否匹配当前设备
|
|
pub fn verify_device_id(device_id: &str) -> Result<bool, ()> {
|
|
let current_device_id = Self::generate_device_id()?;
|
|
Ok(current_device_id == device_id)
|
|
}
|
|
|
|
/// 获取设备ID的短版本(前16字符)
|
|
pub fn generate_short_device_id() -> Result<String, ()> {
|
|
let full_id = Self::generate_device_id()?;
|
|
Ok(full_id[..16].to_string())
|
|
}
|
|
|
|
/// 获取设备信息的详细报告
|
|
pub fn generate_device_report() -> Result<DeviceReport, ()> {
|
|
let device_info = DeviceInfoCollector::collect_device_info()?;
|
|
let device_id = Self::calculate_device_hash(&device_info)?;
|
|
|
|
Ok(DeviceReport {
|
|
device_id,
|
|
device_info,
|
|
generated_at: chrono::Utc::now().to_string(),
|
|
})
|
|
}
|
|
}
|
|
|
|
#[derive(Debug, Clone, Serialize)]
|
|
pub struct DeviceReport {
|
|
pub device_id: String,
|
|
pub device_info: DeviceInfo,
|
|
pub generated_at: String,
|
|
}
|
|
|
|
#[cfg(test)]
|
|
mod tests {
|
|
use DeviceIdGenerator;
|
|
|
|
use super::*;
|
|
|
|
#[test]
|
|
fn test_device_id_generation() {
|
|
let device_id = DeviceIdGenerator::generate_device_id().unwrap();
|
|
assert_eq!(device_id.len(), 64); // SHA256应该是64字符
|
|
|
|
// 验证设备ID一致性
|
|
let device_id2 = DeviceIdGenerator::generate_device_id().unwrap();
|
|
assert_eq!(device_id, device_id2);
|
|
}
|
|
|
|
#[test]
|
|
fn test_device_verification() {
|
|
let device_id = DeviceIdGenerator::generate_device_id().unwrap();
|
|
let is_valid = DeviceIdGenerator::verify_device_id(&device_id).unwrap();
|
|
assert!(is_valid);
|
|
|
|
// 验证错误的设备ID
|
|
let fake_id = "a".repeat(64);
|
|
let is_valid = DeviceIdGenerator::verify_device_id(&fake_id).unwrap();
|
|
assert!(!is_valid);
|
|
}
|
|
|
|
#[test]
|
|
fn test_device_report() {
|
|
let report = DeviceIdGenerator::generate_device_report().unwrap();
|
|
|
|
println!("Device ID: {}", report.device_id);
|
|
println!("Username: {}", report.device_info.username);
|
|
println!("Hostname: {}", report.device_info.hostname);
|
|
println!("OS: {} {}", report.device_info.os_name, report.device_info.os_version);
|
|
println!("CPU: {} {}", report.device_info.cpu_info.vendor_id, report.device_info.cpu_info.brand);
|
|
|
|
assert!(!report.device_id.is_empty());
|
|
assert!(!report.device_info.username.is_empty());
|
|
assert!(!report.device_info.hostname.is_empty());
|
|
}
|
|
}
|