RB_ningyang/generate_activation_code.py
2026-01-22 19:08:28 +08:00

214 lines
6.1 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#!/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())