| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235 |
- # 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)
|