python-给程序增加一个简单的使用期限判断

import os
import uuid
from datetime import datetime, timedelta
import ntplib
from cryptography.fernet import Fernet
from dotenv import load_dotenv
import time
import sys
import socket

# 加载环境变量
load_dotenv()

# 生成或加载密钥
def generate_or_load_key():
    # 获取当前用户的AppData\Local目录路径
    appdata_path = os.environ['LOCALAPPDATA']
    # 使用您的主程序名称作为文件夹名称
    app_folder_name = "Personal authorization"  # 避免和主程序名字相似
    app_folder_path = os.path.join(appdata_path, app_folder_name)
    # 如果文件夹不存在,则创建它
    if not os.path.exists(app_folder_path):
        os.makedirs(app_folder_path)

    # 定义secret.key的完整路径
    key_path = os.path.join(app_folder_path, 'secret.key')
    if not os.path.exists(key_path):
        key = Fernet.generate_key()
        with open(key_path, "wb") as key_file:
            key_file.write(key)
    else:
        key = open(key_path, "rb").read()
    return key, app_folder_path

# 加密数据
def encrypt(data, key):
    f = Fernet(key)
    encrypted_data = f.encrypt(data.encode())
    return encrypted_data

# 解密数据
def decrypt(data, key):
    f = Fernet(key)
    decrypted_data = f.decrypt(data)
    return decrypted_data.decode()

# 获取硬件ID
def get_hardware_id():
    return hex(uuid.getnode())

# 获取网络时间
def get_network_time(retries=3, timeout=5):
    client = ntplib.NTPClient()
    for _ in range(retries):
        try:
            response = client.request('time.windows.com', version=3, timeout=timeout)
            return datetime.utcfromtimestamp(response.tx_time)
        except ntplib.NTPException:
            time.sleep(1)
        except socket.gaierror:
            continue  # 如果发生地址解析错误,继续尝试直到重试次数用完
    # 如果所有尝试都失败了,使用本地系统时间
    return datetime.now()

# 检查是否过期
def check_expiry():
    # 从generate_or_load_key函数获取密钥和app_folder_path
    key, app_folder_path = generate_or_load_key()

    hardware_id = get_hardware_id()
    expiry_file = os.path.join(app_folder_path, 'expiry.info')

    if not os.path.exists(expiry_file):
        # 第一次运行,生成期限校验文件
        expiry_date = (get_network_time() + timedelta(days=30)).strftime('%Y-%m-%d')  # 30天试用期
        data = f"{hardware_id}|{expiry_date}"
        encrypted_data = encrypt(data, key)
        with open(expiry_file, "wb") as file:
            file.write(encrypted_data)
    else:
        # 检查期限
        with open(expiry_file, "rb") as file:
            encrypted_data = file.read()
            data = decrypt(encrypted_data, key)
            saved_hardware_id, expiry_date = data.split('|')
            if saved_hardware_id != hardware_id:
                messagebox.showerror("错误", "硬件ID不匹配,无法使用此程序。")
                exit()  # 退出程序
            current_time = get_network_time()
            if current_time > datetime.strptime(expiry_date, '%Y-%m-%d'):
                messagebox.showinfo("试用期已到", "试用期已到,请联系开发者。")
                sys.exit()  # 退出程序

# 在程序的开始调用check_expiry函数
check_expiry()
  • 4
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值