275 lines
9.8 KiB
Python
275 lines
9.8 KiB
Python
import hashlib
|
|
import platform
|
|
import subprocess
|
|
import sys
|
|
import uuid
|
|
|
|
|
|
def get_windows_machine_code():
|
|
"""获取Windows系统的机器码"""
|
|
try:
|
|
# 尝试获取主板序列号
|
|
try:
|
|
wmic_output = subprocess.check_output(
|
|
'wmic baseboard get serialnumber',
|
|
shell=True,
|
|
stderr=subprocess.STDOUT,
|
|
timeout=10
|
|
).decode().strip()
|
|
|
|
if "SerialNumber" in wmic_output:
|
|
lines = [line.strip() for line in wmic_output.split("\n") if line.strip()]
|
|
if len(lines) > 1:
|
|
serial = lines[1]
|
|
if serial and serial not in ["To Be Filled By O.E.M.", "Default string", "N/A", ""]:
|
|
return hashlib.md5(serial.encode()).hexdigest()[:16].upper()
|
|
except:
|
|
pass
|
|
|
|
# 尝试获取硬盘序列号
|
|
try:
|
|
wmic_output = subprocess.check_output(
|
|
'wmic diskdrive get serialnumber',
|
|
shell=True,
|
|
stderr=subprocess.STDOUT,
|
|
timeout=10
|
|
).decode().strip()
|
|
|
|
if "SerialNumber" in wmic_output:
|
|
lines = [line.strip() for line in wmic_output.split("\n") if line.strip()]
|
|
for line in lines[1:]: # 跳过标题行
|
|
if line and line not in ["", "N/A"]:
|
|
return hashlib.md5(line.encode()).hexdigest()[:16].upper()
|
|
except:
|
|
pass
|
|
|
|
# 尝试获取CPU序列号
|
|
try:
|
|
wmic_output = subprocess.check_output(
|
|
'wmic cpu get processorid',
|
|
shell=True,
|
|
stderr=subprocess.STDOUT,
|
|
timeout=10
|
|
).decode().strip()
|
|
|
|
if "ProcessorId" in wmic_output:
|
|
lines = [line.strip() for line in wmic_output.split("\n") if line.strip()]
|
|
if len(lines) > 1:
|
|
cpu_id = lines[1]
|
|
if cpu_id and cpu_id != "":
|
|
return hashlib.md5(cpu_id.encode()).hexdigest()[:16].upper()
|
|
except:
|
|
pass
|
|
|
|
# 尝试获取BIOS序列号
|
|
try:
|
|
wmic_output = subprocess.check_output(
|
|
'wmic bios get serialnumber',
|
|
shell=True,
|
|
stderr=subprocess.STDOUT,
|
|
timeout=10
|
|
).decode().strip()
|
|
|
|
if "SerialNumber" in wmic_output:
|
|
lines = [line.strip() for line in wmic_output.split("\n") if line.strip()]
|
|
if len(lines) > 1:
|
|
bios_serial = lines[1]
|
|
if bios_serial and bios_serial not in ["To Be Filled By O.E.M.", "Default string", "N/A", ""]:
|
|
return hashlib.md5(bios_serial.encode()).hexdigest()[:16].upper()
|
|
except:
|
|
pass
|
|
|
|
# 组合多个系统信息生成唯一标识
|
|
try:
|
|
# 获取网卡MAC地址
|
|
mac = uuid.getnode()
|
|
mac_str = ':'.join(['{:02x}'.format((mac >> elements) & 0xff) for elements in range(0, 2 * 6, 2)][::-1])
|
|
|
|
# 获取计算机名
|
|
computer_name = platform.node()
|
|
|
|
# 获取系统信息
|
|
system_info = f"{platform.system()}-{platform.release()}-{platform.version()}"
|
|
|
|
# 组合信息
|
|
combined_info = f"{mac_str}-{computer_name}-{system_info}"
|
|
return hashlib.md5(combined_info.encode()).hexdigest()[:16].upper()
|
|
|
|
except Exception as e:
|
|
# 最后的备用方案
|
|
fallback = f"{platform.uname()}-{uuid.getnode()}"
|
|
return hashlib.md5(fallback.encode()).hexdigest()[:16].upper()
|
|
|
|
except Exception as e:
|
|
print(f"获取Windows机器码错误: {e}")
|
|
# 生成一个基于系统信息的备用哈希
|
|
try:
|
|
fallback = f"{platform.node()}-{uuid.getnode()}-{platform.processor()}"
|
|
return hashlib.md5(fallback.encode()).hexdigest()[:16].upper()
|
|
except:
|
|
# 终极备用方案
|
|
import time
|
|
fallback = f"FALLBACK-{int(time.time())}-{platform.system()}"
|
|
return hashlib.md5(fallback.encode()).hexdigest()[:16].upper()
|
|
|
|
|
|
def get_linux_machine_code():
|
|
"""获取Linux系统的机器码"""
|
|
try:
|
|
# 尝试读取machine-id
|
|
try:
|
|
with open('/etc/machine-id', 'r') as f:
|
|
machine_id = f.read().strip()
|
|
if machine_id and len(machine_id) > 10:
|
|
return machine_id[:16].upper()
|
|
except:
|
|
pass
|
|
|
|
# 尝试读取/var/lib/dbus/machine-id
|
|
try:
|
|
with open('/var/lib/dbus/machine-id', 'r') as f:
|
|
machine_id = f.read().strip()
|
|
if machine_id and len(machine_id) > 10:
|
|
return machine_id[:16].upper()
|
|
except:
|
|
pass
|
|
|
|
# 尝试获取主板信息
|
|
try:
|
|
with open('/sys/class/dmi/id/board_serial', 'r') as f:
|
|
board_serial = f.read().strip()
|
|
if board_serial and board_serial not in ["", "N/A", "To be filled by O.E.M."]:
|
|
return hashlib.md5(board_serial.encode()).hexdigest()[:16].upper()
|
|
except:
|
|
pass
|
|
|
|
# 尝试获取产品UUID
|
|
try:
|
|
with open('/sys/class/dmi/id/product_uuid', 'r') as f:
|
|
product_uuid = f.read().strip()
|
|
if product_uuid and product_uuid != "":
|
|
return hashlib.md5(product_uuid.encode()).hexdigest()[:16].upper()
|
|
except:
|
|
pass
|
|
|
|
# 获取MAC地址和主机名组合
|
|
mac = uuid.getnode()
|
|
mac_str = ':'.join(['{:02x}'.format((mac >> elements) & 0xff) for elements in range(0, 2 * 6, 2)][::-1])
|
|
hostname = platform.node()
|
|
combined = f"{mac_str}-{hostname}"
|
|
return hashlib.md5(combined.encode()).hexdigest()[:16].upper()
|
|
|
|
except Exception as e:
|
|
print(f"获取Linux机器码错误: {e}")
|
|
# 备用方案
|
|
system_info = f"{platform.node()}-{uuid.getnode()}-{platform.machine()}"
|
|
return hashlib.md5(system_info.encode()).hexdigest()[:16].upper()
|
|
|
|
|
|
def get_mac_machine_code():
|
|
"""获取macOS系统的机器码"""
|
|
try:
|
|
# 尝试获取硬件UUID
|
|
try:
|
|
result = subprocess.check_output(
|
|
['system_profiler', 'SPHardwareDataType'],
|
|
stderr=subprocess.STDOUT,
|
|
timeout=10
|
|
).decode().strip()
|
|
|
|
for line in result.split('\n'):
|
|
if 'Hardware UUID' in line:
|
|
uuid_part = line.split(':')[1].strip()
|
|
return hashlib.md5(uuid_part.encode()).hexdigest()[:16].upper()
|
|
except:
|
|
pass
|
|
|
|
# 尝试获取序列号
|
|
try:
|
|
serial = subprocess.check_output(
|
|
['system_profiler', 'SPHardwareDataType', '|', 'grep', 'Serial'],
|
|
shell=True,
|
|
stderr=subprocess.STDOUT,
|
|
timeout=10
|
|
).decode().strip()
|
|
|
|
if serial:
|
|
serial_number = serial.split(':')[1].strip()
|
|
return hashlib.md5(serial_number.encode()).hexdigest()[:16].upper()
|
|
except:
|
|
pass
|
|
|
|
# 备用方案
|
|
mac = uuid.getnode()
|
|
hostname = platform.node()
|
|
combined = f"{mac}-{hostname}-{platform.machine()}"
|
|
return hashlib.md5(combined.encode()).hexdigest()[:16].upper()
|
|
|
|
except Exception as e:
|
|
print(f"获取macOS机器码错误: {e}")
|
|
# 备用方案
|
|
system_info = f"{platform.node()}-{uuid.getnode()}-{platform.machine()}"
|
|
return hashlib.md5(system_info.encode()).hexdigest()[:16].upper()
|
|
|
|
|
|
def get_machine_code():
|
|
"""获取当前系统的机器码"""
|
|
try:
|
|
system = platform.system()
|
|
|
|
if system == "Windows":
|
|
return get_windows_machine_code()
|
|
elif system == "Linux":
|
|
return get_linux_machine_code()
|
|
elif system == "Darwin": # macOS
|
|
return get_mac_machine_code()
|
|
else:
|
|
# 未知系统,使用通用方法
|
|
system_info = f"{platform.node()}-{uuid.getnode()}-{platform.processor()}-{platform.machine()}"
|
|
return hashlib.md5(system_info.encode()).hexdigest()[:16].upper()
|
|
|
|
except Exception as e:
|
|
print(f"获取机器码失败: {e}")
|
|
# 终极备用方案
|
|
try:
|
|
fallback = f"{platform.system()}-{uuid.getnode()}-{platform.node()}"
|
|
return hashlib.md5(fallback.encode()).hexdigest()[:16].upper()
|
|
except:
|
|
import time
|
|
ultimate_fallback = f"MACHINE-{int(time.time())}"
|
|
return hashlib.md5(ultimate_fallback.encode()).hexdigest()[:16].upper()
|
|
|
|
|
|
def format_machine_code(machine_code):
|
|
"""格式化机器码为更易读的格式"""
|
|
if len(machine_code) >= 16:
|
|
# 将16位机器码格式化为 XXXX-XXXX-XXXX-XXXX
|
|
return f"{machine_code[:4]}-{machine_code[4:8]}-{machine_code[8:12]}-{machine_code[12:16]}"
|
|
else:
|
|
return machine_code
|
|
|
|
|
|
def verify_machine_code(stored_code, current_code):
|
|
"""验证机器码是否匹配"""
|
|
# 移除格式化字符进行比较
|
|
stored_clean = stored_code.replace('-', '').upper()
|
|
current_clean = current_code.replace('-', '').upper()
|
|
return stored_clean == current_clean
|
|
|
|
|
|
if __name__ == "__main__":
|
|
print("机器码生成器测试")
|
|
print("-" * 30)
|
|
|
|
machine_code = get_machine_code()
|
|
formatted_code = format_machine_code(machine_code)
|
|
|
|
print(f"系统: {platform.system()} {platform.release()}")
|
|
print(f"原始机器码: {machine_code}")
|
|
print(f"格式化机器码: {formatted_code}")
|
|
print(f"机器码长度: {len(machine_code)}")
|
|
|
|
# 测试验证功能
|
|
print(f"\n验证测试: {verify_machine_code(formatted_code, machine_code)}")
|
|
|
|
input("\n按回车键退出...") |