Qt编写密钥生成器+使用demo(开源)
在很多商业软件中,需要提供一些可以试运行的版本,这样就需要配套密钥机制来控制,纵观大部分的试用版软件,基本上采用以下几种机制来控制。
1:远程联网激活,每次启动都联网查看使用时间等,这种方法最完美,缺点是没法联网的设备就歇菜了。
2:通过获取本地的硬盘+CPU等硬件的编号,做一个运算,生成一个激活码,超过半数的软件会采用此方法,缺点是不能自由控制软件的其他参数,比如软件中添加的设备数量的控制。
3:设定一个运行到期时间+数量限制+已运行时间的密钥文件,发给用户配套软件使用,缺点是如果仅仅设置的是运行到期时间,用户可以更改电脑时间来获取更长的使用时间,在电脑不联网的情况下。
本demo采用抛砖引玉的形式,用第三种方法来实现,密钥文件采用最简单的异或加密,可以自行改成其他加密方法。
完整代码下载地址:https://download.csdn.net/download/feiyangqingyun/10975625
核心代码:
- #include "frmmain.h"
- #include "ui_frmmain.h"
- #include "qmessagebox.h"
- #include "qfile.h"
- frmMain::frmMain(QWidget *parent) : QWidget(parent), ui(new Ui::frmMain)
- {
- ui->setupUi(this);
- this->initForm();
- }
- frmMain::~frmMain()
- {
- delete ui;
- }
- void frmMain::initForm()
- {
- QStringList min;
- min << "" << "" << "" << "" << "";
- for (int i = ; i <= ; i++) {
- min << QString::number(i * );
- }
- ui->cboxMin->addItems(min);
- ui->cboxMin->setCurrentIndex();
- ui->dateEdit->setDate(QDate::currentDate());
- for (int i = ; i <= ; i = i + ) {
- ui->cboxCount->addItem(QString("%1").arg(i));
- }
- }
- QString frmMain::getXorEncryptDecrypt(const QString &data, char key)
- {
- //采用异或加密,也可以自行更改算法
- QByteArray buffer = data.toLatin1();
- int size = buffer.size();
- for (int i = ; i < size; i++) {
- buffer[i] = buffer.at(i) ^ key;
- }
- return QLatin1String(buffer);
- }
- void frmMain::on_btnOk_clicked()
- {
- bool useDate = ui->ckDate->isChecked();
- bool useRun = ui->ckRun->isChecked();
- bool useCount = ui->ckCount->isChecked();
- if (!useDate && !useRun && !useCount) {
- if (QMessageBox::question(this, "询问", "确定要生成没有任何限制的密钥吗?") != QMessageBox::Yes) {
- return;
- }
- }
- QString strDate = ui->dateEdit->date().toString("yyyy-MM-dd");
- QString strRun = ui->cboxMin->currentText();
- QString strCount = ui->cboxCount->currentText();
- QString key = QString("%1|%2|%3|%4|%5|%6").arg(useDate).arg(strDate).arg(useRun).arg(strRun).arg(useCount).arg(strCount);
- QFile file(QApplication::applicationDirPath() + "/key.db");
- file.open(QFile::WriteOnly | QIODevice::Text);
- file.write(getXorEncryptDecrypt(key, ).toLatin1());
- file.close();
- QMessageBox::information(this, "提示", "生成密钥成功,将 key.db 文件拷贝到对应目录即可!");
- }
- void frmMain::on_btnClose_clicked()
- {
- this->close();
- }
使用demo封装类代码:
- #include "appkey.h"
- #include "qmutex.h"
- #include "qfile.h"
- #include "qtimer.h"
- #include "qdatetime.h"
- #include "qapplication.h"
- #include "qmessagebox.h"
- AppKey *AppKey::self = NULL;
- AppKey *AppKey::Instance()
- {
- if (!self) {
- QMutex mutex;
- QMutexLocker locker(&mutex);
- if (!self) {
- self = new AppKey;
- }
- }
- return self;
- }
- AppKey::AppKey(QObject *parent) : QObject(parent)
- {
- keyData = "";
- keyUseDate = false;
- keyDate = "2017-01-01";
- keyUseRun = false;
- keyRun = ;
- keyUseCount = false;
- keyCount = ;
- timer = new QTimer(this);
- timer->setInterval();
- connect(timer, SIGNAL(timeout()), this, SLOT(checkTime()));
- startTime = QDateTime::currentDateTime();
- }
- void AppKey::start()
- {
- //判断密钥文件是否存在,不存在则从资源文件复制出来,同时需要设置文件写权限
- QString keyName = qApp->applicationDirPath() + "/key.db";
- QFile keyFile(keyName);
- if (!keyFile.exists() || keyFile.size() == ) {
- QMessageBox::critical(, "错误", "密钥文件丢失,请联系供应商!");
- exit();
- }
- //读取密钥文件
- keyFile.open(QFile::ReadOnly);
- keyData = keyFile.readLine();
- keyFile.close();
- //将从注册码文件中的密文解密,与当前时间比较是否到期
- keyData = getXorEncryptDecrypt(keyData, );
- QStringList data = keyData.split("|");
- if (data.count() != ) {
- QMessageBox::critical(, "错误", "注册码文件已损坏,程序将自动关闭!");
- exit();
- }
- keyUseDate = (data.at() == "" ? true : false);
- keyDate = data.at();
- keyUseRun = (data.at() == "" ? true : false);
- keyRun = data.at().toInt();
- keyUseCount = (data.at() == "" ? true : false);
- keyCount = data.at().toInt();
- //如果启用了时间限制
- if (keyUseDate) {
- QString nowDate = QDate::currentDate().toString("yyyy-MM-dd");
- if (nowDate > keyDate) {
- QMessageBox::critical(, "错误", "软件已到期,请联系供应商更新注册码!");
- exit();
- }
- }
- //如果启用了运行时间显示
- if (keyUseRun) {
- timer->start();
- }
- }
- void AppKey::stop()
- {
- timer->stop();
- }
- void AppKey::checkTime()
- {
- //找出当前时间与首次启动时间比较
- QDateTime now = QDateTime::currentDateTime();
- if (startTime.secsTo(now) >= (keyRun * )) {
- QMessageBox::critical(, "错误", "试运行时间已到,请联系供应商更新注册码!");
- exit();
- }
- }
- QString AppKey::getXorEncryptDecrypt(const QString &data, char key)
- {
- //采用异或加密,也可以自行更改算法
- QByteArray buffer = data.toLatin1();
- int size = buffer.size();
- for (int i = ; i < size; i++) {
- buffer[i] = buffer.at(i) ^ key;
- }
- return QLatin1String(buffer);
- }
- bool AppKey::checkCount(int count)
- {
- if (keyUseCount) {
- if (count >= keyCount) {
- QMessageBox::critical(, "错误", "设备数量超过限制,请联系供应商更新注册码!");
- return false;
- }
- }
- return true;
- }
Qt编写密钥生成器+使用demo(开源)的更多相关文章
- 年底奉献-QT编写视频监管平台(开源)
忙忙碌碌又是一年,算算自己毕业四年半,一直在现在这家公司做研发外加总经理助理,研发起初用的VB.NET,而后全面转为C#,最后又全面转为QT,都是由于项目需要,算下来自己搞QT编程也已经四年了,201 ...
- Qt编写软件运行时间记录(开源)
在早期开发的软件中,尤其是初学者入门者写的软件,软件运行久了,难免遇到意外崩溃的时候,可是大部分的运行设备可能在现场客户那,需要记住每一次从软件启动后到软件意外关闭前的运行时间,需要记录的信息包括:编 ...
- Qt编写网络中转服务器(开源)
需求1:手机端或者其他端可以对设备进行回控,并查看设备各种运行状态,接收报警推送等.2:同时支持在局域网.广域网.互联网访问,尤其是互联网访问.3:权限控制,给定账号控制授权的设备,并自动拉取设备信息 ...
- Qt编写的开源帖子集合(懒人专用)
回顾自己学习Qt以来九年了,在这九年多时间里面,从本论坛学习不到不少的东西,今天特意整了一下自己开源过的资源的帖子,整理一起方便大家直接跳转下载,不统计不知道,一统计吓一跳,不知不觉开源了这么多代码, ...
- Qt编写自定义控件插件开放动态库dll使用(永久免费)
这套控件陆陆续续完善了四年多,目前共133个控件,除了十几个控件参考网友开源的代码写的,其余全部原创,在发布之初就有打算将动态库开放出来永久免费使用,在控件比较完善的今天抽了半天时间编译了多个qt版本 ...
- Qt编写自定义控件5-柱状温度计
前言 柱状温度计控件,可能是很多人练手控件之一,基本上都是垂直方向展示,底部一个水银柱,中间刻度尺,刻度尺可以在左侧右侧或者两侧都有,自适应分辨率改动,有时候为了美观效果,可能还会整个定时器来实现动画 ...
- Qt编写项目作品大全(自定义控件+输入法+大屏电子看板+视频监控+楼宇对讲+气体安全等)
一.自定义控件大全 (一).控件介绍 超过160个精美控件,涵盖了各种仪表盘.进度条.进度球.指南针.曲线图.标尺.温度计.导航条.导航栏,flatui.高亮按钮.滑动选择器.农历等.远超qwt集成的 ...
- Qt编写气体安全管理系统10-数据导出
一.前言 数据导出一般指导出到excel表格,可能有部分用户还需要导出到pdf,因为pdf基本上不可编辑,防止用户重新编辑导出的数据,excel可能绝大部分用过电脑的人都知道,广为流行,主要就是微软的 ...
- Qt编写自定义控件71-圆弧进度条
一.前言 现在web形式的图表框架非常流行,国产代表就是echart,本人用过几次,三个字屌爆了来形容,非常强大,而且易用性也非常棒,还是开源免费的,使用起来不要太爽,内置的各种图表和仪表盘等非常丰富 ...
随机推荐
- 用不上索引的SQL语句
下面介绍六种建立索引后不起作用的sql语句. 1.使用不等于操作符(<>, !=) SELECT * FROM dept WHERE staff_num <> 1000; × ...
- js Jquery字符UrlEncode 编码 C#(asp.net)解码 Server HttpUtility 区别 cookies存中文
一.Js asp.net 交互Url编码解码 C#(asp.net)编码:HttpUtility.UrlEncode(url) Jquery解码:decodeURIComponent(url); Jq ...
- 深入浅出:全面理解SQL Server权限体系
转自IT168 好文转载存档! [IT168 技术]权限两个字,一个权力,一个限制.在软件领域通俗的解释就是哪些人可以对哪些资源做哪些操作.在SQL Server中,"哪些人", ...
- 腾讯游戏设计(tgideas.qq.com)回复处CSRF任意换马甲
http://tgideas.qq.com GET /cgi-bin/comments/sendreply.cgi?iActivId=1&iSubActivId=215722&iPar ...
- vue学习起步,vue环境安装
vue安装的前提是安装了nodejs 安装淘宝镜像 npm install -g cnpm --registry=https://registry.npm.taobao.org 安装webpack c ...
- Win7 共享打印机 “错误:共享无法保存设置”
原因:windows的后台防火墙服务进程[Windows Firewall{服务描述}.MpsSvc{服务名字}] 关闭了.services.smc 关闭 解决:重启服务 关闭防火墙的功能,通过控制面 ...
- QT 实现QGraphicsProxyWidget对象可选择或移动(item管理实现)
上篇博文<QT QGraphicsProxyWidget对象可选择或移动的一些tricks>介绍了实现QT QGraphicsProxyWidget对象可选择或移动的一些小的第三方技巧,但 ...
- jsavascript 面向对象的下拉菜单
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/ ...
- 【11-13】A股主要指数的市盈率(PE)估值高度
全指材料(SH000987) - 2018-11-13日,当前值:12.4646,平均值:30.54,中位数:26.09865,当前 接近历史新低.全指材料(SH000987)的历史市盈率PE详情 内 ...
- node.js--Less
摘要: 现在已经有许多站点使用Node.js,所以在Node.js上配置Less环境也是很重要的,下面分享下如何在Node上使用Less开发,前提是你电脑上已经安装node. 安装: 只需要执行下面一 ...