2025-08-09通过授权码的方式给exe程序充值

2025-08-09通过授权码的方式给exe程序充值

image-20250809235816328

主要点:

一次性授权机制:
新增 .used_licenses 文件记录所有已使用的授权码
每次激活前检查授权码是否在已使用列表中
激活成功后立即将授权码标记为已使用
时效性验证:
授权码包含过期时间戳(默认 24 小时有效)
超过有效期的授权码无法使用
防止用户长期保存授权码多次使用
授权码格式升级:
新格式:次数|过期时间戳|哈希值(例如:50|1620000000|xxxxxxxxxxx)
时间戳精确到分钟,确保唯一性

使用流程:

开发者生成授权码:
运行 license_generator.py
输入次数(如 50)和有效期(如 24 小时)
生成授权码并发送给用户
用户使用授权码:
在程序中输入授权码并激活
系统验证通过后增加次数并记录此授权码
再次使用同一授权码会提示 “已被使用”

image-20250809235415756

首先创建一个授权码生成工具(开发者使用):

import os
import time
import threading
import hashlib
import ctypes
from datetime import datetime
from PyQt5.QtWidgets import (QApplication, QMainWindow, QWidget, QVBoxLayout,QHBoxLayout, QLabel, QTextEdit, QPushButton, QProgressBar, QMessageBox, QLineEdit, QDialog)
from PyQt5.QtCore import Qt, pyqtSignal, QObject
from PyQt5.QtGui import QTextOption, QFont
from DrissionPage import ChromiumPage
from lxml import etree
import requests
from concurrent.futures import ThreadPoolExecutor, as_completed
import randomDEVELOPER_INFO = """
已超过试用次数,请联系开发者。
邮箱: xurennie@qq.com
微信:X331752133
需备注添加微信来意,谢谢!
"""PRICING_INFO = """
价格说明:
- 0.05元/URL(每个项目链接)
- 最低充值金额:5元(可下载约100个项目)
- 批量购买可享受优惠,详情请咨询开发者使用说明:
1. 在输入框中填写Behance项目URL,多个URL用逗号分隔
2. 点击"开始下载"按钮进行下载
3. 每次下载会消耗1次使用次数
4. 次数用尽后,请联系开发者充值
5. 充值后将获得授权码,输入授权码即可继续使用联系方式:
邮箱: xurennie@qq.com
微信:X331752133
(添加微信时请备注:Behance下载器充值)
"""LICENSE_KEY = b"behance_downloader_license_key_2024"class LicenseManager:def __init__(self):self.license_file = self.get_secure_license_path()self.used_codes_file = os.path.join(os.path.dirname(self.license_file), ".used_licenses")if not self.license_file:QMessageBox.critical(None, "错误", "无法找到合适的位置存储授权文件\n程序将退出")os._exit(1)self.ensure_license_file()self.ensure_used_codes_file()def get_secure_license_path(self):candidate_paths = []try:if os.name == 'nt':appdata = os.environ.get('APPDATA')if appdata:path1 = os.path.join(appdata, ".BehanceData", "config")candidate_paths.append(path1)localappdata = os.environ.get('LOCALAPPDATA')if localappdata:path2 = os.path.join(localappdata, ".BehanceData", "config")candidate_paths.append(path2)doc_path = os.path.join(os.path.expanduser("~"), "Documents", ".BehanceData")candidate_paths.append(doc_path)exe_dir = os.path.dirname(os.path.abspath(__file__))path4 = os.path.join(exe_dir, ".BehanceData")candidate_paths.append(path4)temp_path = os.environ.get('TEMP', os.path.join(os.path.expanduser("~"), "Temp"))path5 = os.path.join(temp_path, ".BehanceData")candidate_paths.append(path5)else:candidate_paths.append(os.path.join(os.path.expanduser("~"), ".behance_data", "config"))candidate_paths.append(os.path.join(os.path.expanduser("~"), ".config", "behance_data"))candidate_paths.append(os.path.join(os.path.dirname(os.path.abspath(__file__)), ".behance_data"))except Exception as e:print(f"路径生成错误: {e}")for path in candidate_paths:try:os.makedirs(path, exist_ok=True)if os.name == 'nt':try:ctypes.windll.kernel32.SetFileAttributesW(path, 0x02)except:passtest_file = os.path.join(path, ".license_test")with open(test_file, 'w') as f:f.write("test")os.remove(test_file)return os.path.join(path, ".license")except:continuereturn Nonedef _encrypt_data(self, data):hash_obj = hashlib.sha256(LICENSE_KEY)hash_obj.update(str(data).encode())return f"{data}|{hash_obj.hexdigest()}"def _decrypt_data(self, encrypted_data):try:data_part, hash_part = encrypted_data.split('|', 1)hash_obj = hashlib.sha256(LICENSE_KEY)hash_obj.update(data_part.encode())if hash_obj.hexdigest() == hash_part:return data_partreturn Noneexcept:return Nonedef ensure_license_file(self):try:if not os.path.exists(self.license_file):with open(self.license_file, 'w') as f:f.write(self._encrypt_data("30"))except Exception as e:QMessageBox.critical(None, "错误", f"无法创建授权文件: {str(e)}\n程序将退出")os._exit(1)def ensure_used_codes_file(self):"""确保已使用授权码记录文件存在"""try:if not os.path.exists(self.used_codes_file):with open(self.used_codes_file, 'w') as f:f.write("")  # 创建空文件# 设置为隐藏文件if os.name == 'nt':try:ctypes.windll.kernel32.SetFileAttributesW(self.used_codes_file, 0x02)except:passexcept:passdef read_use_count(self):if not os.path.exists(self.license_file):return 0try:with open(self.license_file, 'r') as f:content = f.read().strip()data = self._decrypt_data(content)if data is None:return 0return int(data) if data.isdigit() else 0except:return 0def write_use_count(self, count):try:with open(self.license_file, 'w') as f:f.write(self._encrypt_data(str(count)))return Trueexcept:return Falsedef check_license(self):remaining = self.read_use_count()if remaining <= 0:return False, "试用次数已用完"return True, f"剩余试用次数: {remaining}"def update_license(self):remaining = self.read_use_count()if remaining > 0:self.write_use_count(remaining - 1)def is_code_used(self, license_code):"""检查授权码是否已被使用"""try:if os.path.exists(self.used_codes_file):with open(self.used_codes_file, 'r') as f:used_codes = f.read().splitlines()return license_code in used_codesreturn Falseexcept:return False  # 读取失败时默认视为已使用,提高安全性def mark_code_as_used(self, license_code):"""标记授权码为已使用"""try:with open(self.used_codes_file, 'a') as f:f.write(f"{license_code}\n")return Trueexcept:return Falsedef add_uses(self, license_code):"""添加使用次数(通过一次性授权码)"""try:# 检查授权码是否已使用if self.is_code_used(license_code):return False, "此授权码已被使用,请联系开发者获取新的授权码"# 解析授权码parts = license_code.split('|')if len(parts) != 3:return False, "授权码格式错误"additional_uses_str, expire_timestamp_str, hash_part = parts# 验证授权码data = f"{additional_uses_str}|{expire_timestamp_str}"hash_obj = hashlib.sha256(LICENSE_KEY)hash_obj.update(data.encode())if hash_obj.hexdigest() != hash_part:return False, "授权码无效"# 验证时间有效性current_timestamp = int(time.time() // 60)expire_timestamp = int(expire_timestamp_str)if current_timestamp > expire_timestamp:return False, "授权码已过期,请联系开发者获取新的授权码"# 验证次数是否为正整数additional_uses = int(additional_uses_str)if additional_uses <= 0:return False, "授权码无效"# 增加次数current_uses = self.read_use_count()new_uses = current_uses + additional_usesif not self.write_use_count(new_uses):return False, "更新次数失败"# 标记为已使用self.mark_code_as_used(license_code)return True, f"成功增加 {additional_uses} 次使用次数,当前剩余: {new_uses} 次"except ValueError:return False, "授权码包含无效数字"except Exception as e:return False, f"处理失败: {str(e)}"class HelpDialog(QDialog):"""帮助对话框,显示价格信息和使用说明"""def __init__(self, parent=None):super().__init__(parent)self.setWindowTitle("使用帮助")self.setGeometry(200, 200, 500, 400)self.init_ui()def init_ui(self):layout = QVBoxLayout()# 创建文本编辑框显示帮助信息help_text = QTextEdit()help_text.setReadOnly(True)help_text.setPlainText(PRICING_INFO)# 设置字体,使内容更易读font = QFont()font.setPointSize(10)help_text.setFont(font)# 添加关闭按钮close_btn = QPushButton("关闭")close_btn.clicked.connect(self.close)# 添加到布局layout.addWidget(help_text)layout.addWidget(close_btn)self.setLayout(layout)class Communicate(QObject):update_signal = pyqtSignal(str)progress_signal = pyqtSignal(int)status_signal = pyqtSignal(str)license_check_signal = pyqtSignal(bool, str)class BehanceDownloaderGUI(QMainWindow):def __init__(self):super().__init__()self.setWindowTitle("Behance图片下载器(可根据个人需求定制)")self.setGeometry(100, 100, 800, 600)self.license = LicenseManager()self.comm = Communicate()self.init_ui()self.check_license_on_start()self.comm.update_signal.connect(self.log)self.comm.progress_signal.connect(self.update_progress)self.comm.status_signal.connect(self.update_status)self.comm.license_check_signal.connect(self.handle_license_check)def init_ui(self):central_widget = QWidget()self.setCentralWidget(central_widget)layout = QVBoxLayout()# 顶部按钮区域:授权码输入和帮助按钮top_layout = QVBoxLayout()# 授权码输入区域license_layout = QHBoxLayout()self.license_input = QLineEdit()self.license_input.setPlaceholderText("输入授权码以增加使用次数(每次需新授权码)")self.activate_btn = QPushButton("激活授权码")self.activate_btn.clicked.connect(self.activate_license)license_layout.addWidget(self.license_input)license_layout.addWidget(self.activate_btn)# 帮助按钮行help_layout = QHBoxLayout()help_layout.setAlignment(Qt.AlignRight)  # 右对齐self.help_btn = QPushButton("使用帮助")self.help_btn.clicked.connect(self.show_help)help_layout.addWidget(self.help_btn)# 将授权码布局和帮助按钮布局添加到顶部布局top_layout.addLayout(license_layout)top_layout.addLayout(help_layout)layout.addLayout(top_layout)# URL输入标签self.url_label = QLabel("Behance作品URL:")self.url_label.setWordWrap(True)# URL输入self.url_entry = QTextEdit()self.url_entry.setMaximumHeight(80)self.url_entry.setWordWrapMode(QTextOption.WrapAnywhere)self.url_entry.setPlaceholderText("支持多个url项目下载,每个url用英文输入状态下的,号隔开,示例:https://www.behance.net/url-1,https://www.behance.net/url-2")# 下载按钮self.download_btn = QPushButton("开始下载")self.download_btn.clicked.connect(self.start_download)# 进度条self.progress = QProgressBar()self.progress.setAlignment(Qt.AlignCenter)# 状态标签self.status_label = QLabel("")self.status_label.setAlignment(Qt.AlignCenter)# 日志区域self.log_text = QTextEdit()self.log_text.setReadOnly(True)# 添加到布局layout.addWidget(self.url_label)layout.addWidget(self.url_entry)layout.addWidget(self.download_btn)layout.addWidget(self.progress)layout.addWidget(self.status_label)layout.addWidget(self.log_text)central_widget.setLayout(layout)def show_help(self):"""显示帮助对话框"""help_dialog = HelpDialog(self)help_dialog.exec_()def activate_license(self):"""处理授权码激活"""code = self.license_input.text().strip()if not code:QMessageBox.warning(self, "提示", "请输入授权码")returnsuccess, msg = self.license.add_uses(code)if success:QMessageBox.information(self, "成功", msg)self.license_input.clear()# 更新状态显示valid, status_msg = self.license.check_license()self.status_label.setText(status_msg)else:QMessageBox.critical(self, "失败", msg)def check_license_on_start(self):valid, msg = self.license.check_license()self.comm.license_check_signal.emit(valid, msg)def handle_license_check(self, valid, msg):if not valid:QMessageBox.critical(self, "授权限制", DEVELOPER_INFO + "\n" + msg)self.status_label.setText(msg)else:self.status_label.setText(msg)def log(self, message):self.log_text.append(message)def update_progress(self, value):self.progress.setValue(value)def update_status(self, text):self.status_label.setText(text)def sanitize_filename(self, filename):invalid_chars = '<>:"/\\|?*'for char in invalid_chars:filename = filename.replace(char, '')filename = filename.strip()if len(filename) > 100:filename = filename[:100]return filename if filename else "untitled"def start_download(self):valid, msg = self.license.check_license()if not valid:QMessageBox.critical(self, "授权限制", DEVELOPER_INFO + "\n" + msg)returnelse:self.status_label.setText(msg)url_text = self.url_entry.toPlainText().strip()if not url_text:QMessageBox.critical(self, "错误", "请输入有效的URL")returnurls = []lines = url_text.split('\n')for line in lines:line = line.strip()if line:line_urls = line.split(',')for url in line_urls:url = url.strip()if url and (url.startswith('http://') or url.startswith('https://')):urls.append(url)if not urls:QMessageBox.critical(self, "错误", "请输入有效的URL")returnself.download_btn.setEnabled(False)self.comm.update_signal.emit(f"开始下载任务,共 {len(urls)} 个项目...")download_thread = threading.Thread(target=self.download_projects,args=(urls,),daemon=True)download_thread.start()if __name__ == "__main__":app = QApplication([])window = BehanceDownloaderGUI()window.show()app.exec_()

2. 然后在主程序中添加授权码输入功能(用户使用)

import hashlib
import time# 必须与主程序中的密钥保持一致
LICENSE_KEY = b"behance_downloader_license_key_2024"def generate_license_code(additional_uses, valid_hours=24):"""生成一次性授权码additional_uses: 增加的次数valid_hours: 授权码有效期(小时),默认24小时"""if not isinstance(additional_uses, int) or additional_uses <= 0:raise ValueError("增加的次数必须是正整数")# 添加时间戳(精确到分钟),确保授权码时效性timestamp = int(time.time() // 60)  # 每分钟更新一次时间戳# 计算过期时间戳expire_timestamp = timestamp + (valid_hours * 60)# 数据格式: 次数|过期时间戳data = f"{additional_uses}|{expire_timestamp}"# 计算哈希值hash_obj = hashlib.sha256(LICENSE_KEY)hash_obj.update(data.encode())hash_value = hash_obj.hexdigest()# 生成授权码(格式:数据|哈希值)return f"{data}|{hash_value}"if __name__ == "__main__":try:uses = int(input("请输入要增加的次数: "))hours = int(input("请输入授权码有效期(小时,默认24): ") or "24")code = generate_license_code(uses, hours)print(f"\n生成的授权码:{code}")print(f"此授权码有效期为{hours}小时")time.sleep(60)except ValueError as e:print(f"错误: {e}")except Exception as e:print(f"发生错误: {str(e)}")

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/pingmian/92473.shtml
繁体地址,请注明出处:http://hk.pswp.cn/pingmian/92473.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

工具类-高效集合差异计算工具DiffWrapper

集合差异工具类-DiffWrapper 原因 在编辑过程中&#xff0c;肯定会存在对于子表的更新操作&#xff0c;这种更新分为三种&#xff1a; 要加的&#xff0c; 要删的&#xff0c;要更新的&#xff0c;并且传参只有一个modifyVO的, 每一个都写有点过于冗余&#xff0c;故考虑提取一…

SimBA算法实现过程

文章目录添加噪声衡量扰动示例数值总结高级索引变量名代码总体代码添加噪声 操作&#xff1a;将频率扰动通过trans( )转为像素域扰动加到原始图像上&#xff08;trans返回频率域转换为像素域的结果&#xff09; expanded (images_batch[remaining_indices] # 原始图像&…

【面试题】cookie和session 的区别

文章目录一、核心定义与存储位置二、关键区别对比三、典型使用场景四、关联与依赖总结在Web开发中&#xff0c; Cookie和 Session是两种常用的状态管理机制&#xff0c;用于在无状态的HTTP协议中保存用户信息&#xff08;如登录状态、偏好设置等&#xff09;。二者的核心区别体…

【机器学习】算法调参的两种方式:网格搜索(枚举)、随机搜索

文章目录一、网格搜索&#xff1a;穷举式的最优解寻找1、数学推导过程1. 搜索空间的数学结构2. 优化问题的数学性质3. 收敛性分析4. 误差分析2、为什么网格搜索有效&#xff1f;1. 全局最优性保证2. 可重现性与稳定性3. 参数敏感性分析3、适用场景与局限性二、随机搜索&#xf…

免费PDF翻译 离线自建

https://github.com/Byaidu/PDFMathTranslate/blob/main/docs/README_zh-CN.md https://github.com/Byaidu/PDFMathTranslate/releases 方法 针对不同的使用案例&#xff0c;我们提供不同的方法来使用我们的程序&#xff1a;1. UV 安装 安装 Python (3.10 < 版本 < 3.12)…

DeepSeek智能考试系统智能体

一、deepseek-app-1.0 1、系统要求 CentOS 7.9Python 3.8Node.js 16MySQL 8.0 2、部署步骤 运行初始化脚本&#xff1a;./scripts/setup.sh初始化数据库&#xff1a;mysql -u root -p < scripts/init_db.sql启动服务&#xff1a;./scripts/start.sh 3、访问地址 前端&…

4深度学习Pytorch-神经网络--损失函数(sigmoid、Tanh、ReLU、LReLu、softmax)

目录 激活函数 1. Sigmoid 2. Tanh 函数&#xff08;双曲正切&#xff09; 3. ReLU 函数 4. Leaky ReLU (LReLU) 5. Softmax 总结对比表 损失函数选择 激活函数 激活函数是神经网络中每个神经元&#xff08;节点&#xff09;的核心组成部分。它接收上一层所有输入的加权…

探索Trae:使用Trae CN爬取 Gitbook 电子书

在以前使用过Cursor&#xff0c;但是后期由于试用资源很少&#xff0c;免费资源用完我就卸载掉啦&#xff0c;最近又需要开展相关工作&#xff0c;因此下载了最新版的Trae。Trae 2.0最近很火&#xff0c;我正好想要爬取某一个Gitbook 电子书&#xff0c;因此尝试使用Trae和Pyth…

嵌入式知识日常问题记录及用法总结(一)

文章目录摘要问题一、内核启动流程1.1 ARM内核上电复位与BootROM执行​启动代码&#xff08;Startup Code&#xff09;执行跳转到用户程序1.2 内存管理问题二、C语言基础2.1 常量指针和指针常量区别2.2.函数指针和指针函数区别2.3 关键字Volatile2.4 队列结构体数据摘要 嵌入式…

使用Navicat备份数据库MySQL、PostGreSQL等

Navicat 支持多种数据库系统&#xff0c;可通过手动或自动方式进行数据备份&#xff0c;整个过程还是相对简单且直观&#xff0c;比自己敲命令行方便多了。一、备份步骤1.1、手动备份1、打开Navicat并连接数据库&#xff1a;首先&#xff0c;启动Navicat并连接到您的MySQL数据库…

Web3: 用ERC-1400革新公司股权激励

大家好&#xff01;今天&#xff0c;我们来聊一个非常酷的话PEG话题&#xff1a;如何利用Web3技术&#xff0c;特别是ERC-1400证券型代币标准&#xff0c;来革新传统的公司股权激励模式。 大家是否想过&#xff0c;派发给员工的期权或限制性股票&#xff08;RSU&#xff09;可以…

【Python 高频 API 速学 ④】

一、为什么是这 4 个&#xff1f; 列表&#xff08;list&#xff09;是 Python 最常用的可变序列&#xff0c; 90 % 的操作可以浓缩成 「增、并、删、排」 四个字&#xff0c; 而这四个字正好对应 append / extend / pop / sort。二、四剑客一览方法作用原地&#xff1f;返回值…

K8S的POD数量限制

#k8s-v1.11.11.查询当前节点的最大pod数kubectl describe nodes | grep pods2.编辑配置文件把单台的pod数量调到150个vim /etc/systemd/system/kubelet.service #添加最大数量--maxPods: 1503.加载配置重启服务systemctl daemon-reload systemctl restart kubelet#k8s-v1.21.41…

OpenAI开源大模型 GPT-OSS 开放权重语言模型解析:技术特性、部署应用及产业影响

注&#xff1a;此文章内容均节选自充电了么创始人&#xff0c;CEO兼CTO陈敬雷老师的新书《GPT多模态大模型与AI Agent智能体》&#xff08;跟我一起学人工智能&#xff09;【陈敬雷编著】【清华大学出版社】 清华《GPT多模态大模型与AI Agent智能体》书籍配套视频课程【陈敬雷…

CSS--后端也有自己的CSS要学

CSS,即Cascading Style Sheets,它描述了网页的表现与展示效果 为了演示CSS,我写了一个简单的index.html 为了使用控制变量法,一开始我先不写style.css文件的内容 右键在默认浏览器里查看页面,看看效果 1-选择器 根据标签名进行匹配,所以也叫元素选择器 页面效果: 根据…

Docker swarm 常用的命令集合

#docker swarm## 初始化单节点Swarm docker swarm init# 部署测试服务 docker service create --name web --publish 8080:80 --replicas 3 nginx:alpine# Manager节点初始化&#xff08;指定IP&#xff09; docker swarm init --advertise-addr 192.168.1.100# 获取加入令牌 M…

231. 2 的幂

Problem: 231. 2 的幂 文章目录思路解题过程复杂度Code思路 2的幂 n 的二进制只有一个1&#xff0c;而 n - 1的二进制则是把 n 的二进制1变0, 0变1。 例&#xff1a;2^24100,34-1011. 解题过程 n & n - 1 0 复杂度 时间复杂度: O(1)O(1)O(1)空间复杂度: O(1)O(1)O(1) Co…

浅尝AI辅助C转Verilog方法

一、常规算法模块的开发流程日常芯片开发工作中&#xff0c;挺多看工作是把C语言转verilog。例如ISP的代码&#xff0c;都很先由算法进行C model的开发&#xff0c;验证完性能后&#xff0c;输出算法原理文档和c代码&#xff1b;数字设计接手&#xff0c;把C语言转换为verilog代…

Redis分布式锁详解:原理、实现与实战案例

目录 1. 什么是分布式锁&#xff1f; 分布式锁的核心要求 2. 基于Redis的分布式锁实现方案 &#xff08;1&#xff09;基础方案&#xff1a;SETNX EXPIRE &#xff08;2&#xff09;优化方案&#xff1a;SET NX PX&#xff08;原子性加锁&#xff09; &#xff08;3&…

【能碳建设1】用AI+开源打造物联网+能碳管理+交易SaaS系统的最短路径实施指南

摘要 本指南为技术小白设计,目标是在最短时间内利用AI工具与开源系统,独立完成一套物联网平台 + 能碳管理平台 + 碳交易系统的SaaS最小可用版本(MVP),并可后续扩展。流程分为目标定义、技术选型、环境搭建、核心功能开发、SaaS化、多租户、上线运维等环节,按天推进,每步…