RB_ningyang/generate_activation_code.py

214 lines
6.1 KiB
Python
Raw Permalink Normal View History

2026-01-22 11:08:28 +00:00
#!/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())