# device_id.py import socket import uuid from typing import Optional, Dict, List import winreg import subprocess import os import hashlib import socket import uuid import platform import re def get_windows_device_id() -> Optional[str]: """Windows: 获取BIOS UUID""" uuid = None # 方法1: 使用wmic命令 try: result = subprocess.run( ["wmic", "csproduct", "get", "uuid"], capture_output=True, text=True, shell=True, creationflags=subprocess.CREATE_NO_WINDOW, ) if result.returncode == 0: # 按行分割,过滤空行 lines = [ line.strip() for line in result.stdout.strip().split("\n") if line.strip() ] # 找到UUID行 for line in lines: if len(line) == 36 and line.count("-") == 4: uuid = line break except Exception as e: print(f"WMIC获取失败: {e}") # 方法2: 如果wmic失败,使用PowerShell if not uuid: try: result = subprocess.run( [ "powershell", "-Command", "(Get-WmiObject -Class Win32_ComputerSystemProduct).UUID", ], capture_output=True, text=True, shell=True, ) if result.returncode == 0: uuid = result.stdout.strip() except Exception as e: print(f"PowerShell获取失败: {e}") # 方法3: 如果PowerShell也失败,使用注册表 if not uuid: try: with winreg.OpenKey( winreg.HKEY_LOCAL_MACHINE, r"SOFTWARE\Microsoft\Windows NT\CurrentVersion", ) as key: uuid, _ = winreg.QueryValueEx(key, "ProductId") except Exception as e: print(f"注册表获取失败: {e}") return uuid def get_linux_machine_id() -> Optional[str]: """Linux: 获取机器ID""" machine_id_paths = [ "/etc/machine-id", # systemd系统 "/var/lib/dbus/machine-id", # 老版本 ] for path in machine_id_paths: if os.path.exists(path): try: with open(path, "r") as f: machine_id = f.read().strip() if machine_id: return machine_id except: continue return None def get_linux_system_uuid() -> Optional[str]: """Linux: 获取系统UUID""" try: if os.path.exists("/sys/devices/virtual/dmi/id/product_uuid"): with open("/sys/devices/virtual/dmi/id/product_uuid", "r") as f: uuid = f.read().strip() if uuid and len(uuid) == 36: return uuid except: pass return None def get_mac_serial_number() -> Optional[str]: """macOS: 获取序列号""" try: result = subprocess.run( ["system_profiler", "SPHardwareDataType"], capture_output=True, text=True ) if result.returncode == 0: output = result.stdout for line in output.split("\n"): if "Serial Number" in line or "序列号" in line: parts = line.split(":") if len(parts) > 1: serial = parts[1].strip() if serial: return serial except: pass return None def get_platform_device_id() -> Optional[str]: """获取平台设备ID""" system = platform.system() if system == "Windows": return get_windows_device_id() elif system == "Linux": # 优先使用系统UUID uuid = get_linux_system_uuid() if uuid: return uuid # 回退到machine-id return get_linux_machine_id() elif system == "Darwin": # macOS return get_mac_serial_number() return None def get_device_id(): """获取设备特征码""" device_id = get_platform_device_id() if device_id: # 清理设备ID clean_id = re.sub(r"[^a-zA-Z0-9]", "", device_id).upper() fingerprint = hashlib.sha256(clean_id.encode()).hexdigest()[:24].upper() else: # 回退方案 info = { "hostname": socket.gethostname(), "system": platform.system(), "machine": platform.machine(), } fingerprint_data = "|".join([f"{k}:{v}" for k, v in sorted(info.items())]) fingerprint = hashlib.sha256(fingerprint_data.encode()).hexdigest()[:24].upper() return fingerprint def get_device_info() -> Dict: """获取系统详细信息""" info = {} try: if platform.system() == "Windows": # 获取Windows产品ID with winreg.OpenKey( winreg.HKEY_LOCAL_MACHINE, r"SOFTWARE\Microsoft\Windows NT\CurrentVersion", ) as key: info["product_id"] = winreg.QueryValueEx(key, "ProductId")[0] info["product_name"] = winreg.QueryValueEx(key, "ProductName")[0] # 获取BIOS UUID result = subprocess.run( ["wmic", "csproduct", "get", "uuid"], capture_output=True, text=True, shell=True, creationflags=subprocess.CREATE_NO_WINDOW, ) if result.returncode == 0: lines = [line.strip() for line in result.stdout.strip().split("\n")] # 过滤掉空行 lines = [line for line in lines if line] if len(lines) > 1: uuid = lines[1] if len(lines) > 1 else lines[0] if uuid and uuid != "": info["bios_uuid"] = uuid # 获取主机名 info["hostname"] = socket.gethostname() except Exception as e: info["error"] = str(e) return info if __name__ == "__main__": device_id = get_device_id() print(f"设备特征码: {device_id}") print(f"设备信息: {get_platform_device_id()}") with winreg.OpenKey( winreg.HKEY_LOCAL_MACHINE, r"SOFTWARE\Microsoft\Windows NT\CurrentVersion", ) as key: uuid, _ = winreg.QueryValueEx(key, "ProductId") print(f"Windows产品ID: {uuid}") # info = get_device_info() # for key, value in info.items(): # print(f" {key}: {value}") system = platform.system() info = { "system": system, "release": platform.release(), "machine": platform.machine(), "node": platform.node(), "hostname": socket.gethostname(), } print(info)