#!/usr/bin/env python3 # -*- coding: utf-8 -*- """ 激活码生成工具 用于根据客户设备UUID生成激活码 使用方法: python generate_activation_code.py <设备UUID> <客户密码> 示例: python generate_activation_code.py "12345678-1234-1234-1234-123456789ABC" "888888" 参数说明: 设备UUID: 客户设备的主板UUID 客户密码: 与程序中 customerPassword 一致的密码 """ import sys import base64 import hashlib # ============ 配置参数 ============ ENCRYPT_KEY = b"GetonAgain2026SecretKey!@#$%" # 加密密钥(必须与程序一致) # ================================== def encrypt(plain_text: str) -> str: """ 加密函数 - 与 C++ LicenseManager::encrypt 完全对应 """ data = plain_text.encode('utf-8') # 第一步:计算SHA256哈希 hash_obj = hashlib.sha256(data) hash_bytes = hash_obj.digest() # 第二步:构造加密数据 = 哈希前8字节 + 原始数据 to_encrypt = hash_bytes[:8] + data # 第三步:多层加密 encrypted = bytearray() for i, byte in enumerate(to_encrypt): c = byte # 第一层:与主密钥XOR c = c ^ ENCRYPT_KEY[i % len(ENCRYPT_KEY)] # 第二层:字节置换(非线性变换) c = (c * 7 + 13) % 256 # 第三层:与位置相关的混淆 c = c ^ ((i * 31 + 17) % 256) encrypted.append(c) # 第四步:Base64编码 return base64.b64encode(bytes(encrypted)).decode('latin-1') def decrypt(encrypted_text: str) -> str: """ 解密函数 - 与 C++ LicenseManager::decrypt 完全对应 """ # Base64解码 encrypted = bytearray(base64.b64decode(encrypted_text.encode('latin-1'))) if len(encrypted) < 9: # 至少8字节校验头 + 1字节数据 return "" # 逆向解密 decrypted = bytearray() for i, byte in enumerate(encrypted): c = byte # 逆向第三层:位置混淆 c = c ^ ((i * 31 + 17) % 256) # 逆向第二层:字节置换的逆运算 # 7 的模逆元是 183 (因为 7 * 183 = 1281 = 5 * 256 + 1) c = ((c + 256 - 13) * 183) % 256 # 逆向第一层:与主密钥XOR c = c ^ ENCRYPT_KEY[i % len(ENCRYPT_KEY)] decrypted.append(c) # 提取校验头和原始数据 stored_hash = bytes(decrypted[:8]) original_data = bytes(decrypted[8:]) # 验证哈希 computed_hash = hashlib.sha256(original_data).digest()[:8] if computed_hash != stored_hash: print("警告: 哈希校验失败,数据可能已损坏") return "" return original_data.decode('utf-8') def generate_activation_code(uuid: str, password: str) -> str: """ 生成激活码 格式: encrypt(UUID:password) """ plain_text = f"{uuid}:{password}" return encrypt(plain_text) def verify_activation_code(activation_code: str, expected_uuid: str, expected_password: str) -> bool: """验证激活码是否有效""" try: decrypted = decrypt(activation_code) if not decrypted or ':' not in decrypted: return False # 使用 rsplit 从右侧分割,只分割一次 parts = decrypted.rsplit(':', 1) uuid = parts[0] password = parts[1] return uuid == expected_uuid and password == expected_password except Exception as e: print(f"验证错误: {e}") return False def save_to_csv(uuid: str, activation_code: str, customer_name: str = ""): """ 将激活记录保存到CSV文件 """ import csv import os from datetime import datetime csv_file = "activation_records.csv" file_exists = os.path.exists(csv_file) # 获取当前时间 activation_time = datetime.now().strftime("%Y-%m-%d %H:%M:%S") try: with open(csv_file, 'a', newline='', encoding='utf-8-sig') as f: writer = csv.writer(f) # 如果文件不存在,先写入表头 if not file_exists: writer.writerow(['序号', '设备UUID', '激活码', '激活时间', '客户名称', '备注']) # 统计当前记录数作为序号 record_num = 1 if file_exists: with open(csv_file, 'r', encoding='utf-8-sig') as rf: record_num = sum(1 for _ in rf) # 包含表头的行数就是新记录的序号 # 写入新记录 writer.writerow([record_num, uuid, activation_code, activation_time, customer_name, '']) print(f"激活记录已保存到: {csv_file}") except Exception as e: print(f"保存CSV记录失败: {e}") def main(): # 检查参数 if len(sys.argv) < 3: print("用法: python generate_activation_code.py <设备UUID> <客户密码>") print("示例: python generate_activation_code.py \"12345678-1234-1234-1234-123456789ABC\" \"888888\"") return 1 uuid = sys.argv[1].strip() password = sys.argv[2].strip() if not uuid: print("错误: UUID 不能为空!") return 1 if not password: print("错误: 密码不能为空!") return 1 # 生成激活码 activation_code = generate_activation_code(uuid, password) # 验证 if not verify_activation_code(activation_code, uuid, password): print("错误: 激活码验证失败!") return 1 # 保存激活码文件 filename = f"license_{uuid[:8]}.gal" try: with open(filename, 'w', encoding='utf-8') as f: f.write(activation_code) except Exception as e: print(f"保存文件失败: {e}") return 1 # 记录到CSV save_to_csv(uuid, activation_code) # 输出结果 print(f"UUID: {uuid}") print(f"密码: {password}") print(f"激活码: {activation_code}") print(f"文件: {filename}") print("完成") return 0 if __name__ == "__main__": sys.exit(main())