在很多商业软件中,需要提供一些可以试运行的版本,这样就需要配套密钥机制来控制,纵观大部分的试用版软件,基本上采用以下几种机制来控制。
1:远程联网激活,每次启动都联网查看使用时间等,这种方法最完美,缺点是没法联网的设备就歇菜了。
2:通过获取本地的硬盘+CPU等硬件的编号,做一个运算,生成一个激活码,超过半数的软件会采用此方法,缺点是不能自由控制软件的其他参数,比如软件中添加的设备数量的控制。
3:设定一个运行到期时间+数量限制+已运行时间的密钥文件,发给用户配套软件使用,缺点是如果仅仅设置的是运行到期时间,用户可以更改电脑时间来获取更长的使用时间,在电脑不联网的情况下。
本demo采用抛砖引玉的形式,用第三种方法来实现,密钥文件采用最简单的异或加密,可以自行改成其他加密方法。

完整代码下载地址:https://download.csdn.net/download/feiyangqingyun/10975625

核心代码:

  1. #include "frmmain.h"
  2. #include "ui_frmmain.h"
  3. #include "qmessagebox.h"
  4. #include "qfile.h"
  5.  
  6. frmMain::frmMain(QWidget *parent) : QWidget(parent), ui(new Ui::frmMain)
  7. {
  8. ui->setupUi(this);
  9. this->initForm();
  10. }
  11.  
  12. frmMain::~frmMain()
  13. {
  14. delete ui;
  15. }
  16.  
  17. void frmMain::initForm()
  18. {
  19. QStringList min;
  20. min << "" << "" << "" << "" << "";
  21. for (int i = ; i <= ; i++) {
  22. min << QString::number(i * );
  23. }
  24.  
  25. ui->cboxMin->addItems(min);
  26. ui->cboxMin->setCurrentIndex();
  27. ui->dateEdit->setDate(QDate::currentDate());
  28.  
  29. for (int i = ; i <= ; i = i + ) {
  30. ui->cboxCount->addItem(QString("%1").arg(i));
  31. }
  32. }
  33.  
  34. QString frmMain::getXorEncryptDecrypt(const QString &data, char key)
  35. {
  36. //采用异或加密,也可以自行更改算法
  37. QByteArray buffer = data.toLatin1();
  38. int size = buffer.size();
  39. for (int i = ; i < size; i++) {
  40. buffer[i] = buffer.at(i) ^ key;
  41. }
  42.  
  43. return QLatin1String(buffer);
  44. }
  45.  
  46. void frmMain::on_btnOk_clicked()
  47. {
  48. bool useDate = ui->ckDate->isChecked();
  49. bool useRun = ui->ckRun->isChecked();
  50. bool useCount = ui->ckCount->isChecked();
  51.  
  52. if (!useDate && !useRun && !useCount) {
  53. if (QMessageBox::question(this, "询问", "确定要生成没有任何限制的密钥吗?") != QMessageBox::Yes) {
  54. return;
  55. }
  56. }
  57.  
  58. QString strDate = ui->dateEdit->date().toString("yyyy-MM-dd");
  59. QString strRun = ui->cboxMin->currentText();
  60. QString strCount = ui->cboxCount->currentText();
  61. QString key = QString("%1|%2|%3|%4|%5|%6").arg(useDate).arg(strDate).arg(useRun).arg(strRun).arg(useCount).arg(strCount);
  62.  
  63. QFile file(QApplication::applicationDirPath() + "/key.db");
  64. file.open(QFile::WriteOnly | QIODevice::Text);
  65. file.write(getXorEncryptDecrypt(key, ).toLatin1());
  66. file.close();
  67. QMessageBox::information(this, "提示", "生成密钥成功,将 key.db 文件拷贝到对应目录即可!");
  68. }
  69.  
  70. void frmMain::on_btnClose_clicked()
  71. {
  72. this->close();
  73. }

使用demo封装类代码:

  1. #include "appkey.h"
  2. #include "qmutex.h"
  3. #include "qfile.h"
  4. #include "qtimer.h"
  5. #include "qdatetime.h"
  6. #include "qapplication.h"
  7. #include "qmessagebox.h"
  8.  
  9. AppKey *AppKey::self = NULL;
  10. AppKey *AppKey::Instance()
  11. {
  12. if (!self) {
  13. QMutex mutex;
  14. QMutexLocker locker(&mutex);
  15. if (!self) {
  16. self = new AppKey;
  17. }
  18. }
  19.  
  20. return self;
  21. }
  22.  
  23. AppKey::AppKey(QObject *parent) : QObject(parent)
  24. {
  25. keyData = "";
  26. keyUseDate = false;
  27. keyDate = "2017-01-01";
  28. keyUseRun = false;
  29. keyRun = ;
  30. keyUseCount = false;
  31. keyCount = ;
  32.  
  33. timer = new QTimer(this);
  34. timer->setInterval();
  35. connect(timer, SIGNAL(timeout()), this, SLOT(checkTime()));
  36. startTime = QDateTime::currentDateTime();
  37. }
  38.  
  39. void AppKey::start()
  40. {
  41. //判断密钥文件是否存在,不存在则从资源文件复制出来,同时需要设置文件写权限
  42. QString keyName = qApp->applicationDirPath() + "/key.db";
  43. QFile keyFile(keyName);
  44. if (!keyFile.exists() || keyFile.size() == ) {
  45. QMessageBox::critical(, "错误", "密钥文件丢失,请联系供应商!");
  46. exit();
  47. }
  48.  
  49. //读取密钥文件
  50. keyFile.open(QFile::ReadOnly);
  51. keyData = keyFile.readLine();
  52. keyFile.close();
  53.  
  54. //将从注册码文件中的密文解密,与当前时间比较是否到期
  55. keyData = getXorEncryptDecrypt(keyData, );
  56. QStringList data = keyData.split("|");
  57.  
  58. if (data.count() != ) {
  59. QMessageBox::critical(, "错误", "注册码文件已损坏,程序将自动关闭!");
  60. exit();
  61. }
  62.  
  63. keyUseDate = (data.at() == "" ? true : false);
  64. keyDate = data.at();
  65. keyUseRun = (data.at() == "" ? true : false);
  66. keyRun = data.at().toInt();
  67. keyUseCount = (data.at() == "" ? true : false);
  68. keyCount = data.at().toInt();
  69.  
  70. //如果启用了时间限制
  71. if (keyUseDate) {
  72. QString nowDate = QDate::currentDate().toString("yyyy-MM-dd");
  73. if (nowDate > keyDate) {
  74. QMessageBox::critical(, "错误", "软件已到期,请联系供应商更新注册码!");
  75. exit();
  76. }
  77. }
  78.  
  79. //如果启用了运行时间显示
  80. if (keyUseRun) {
  81. timer->start();
  82. }
  83. }
  84.  
  85. void AppKey::stop()
  86. {
  87. timer->stop();
  88. }
  89.  
  90. void AppKey::checkTime()
  91. {
  92. //找出当前时间与首次启动时间比较
  93. QDateTime now = QDateTime::currentDateTime();
  94. if (startTime.secsTo(now) >= (keyRun * )) {
  95. QMessageBox::critical(, "错误", "试运行时间已到,请联系供应商更新注册码!");
  96. exit();
  97. }
  98. }
  99.  
  100. QString AppKey::getXorEncryptDecrypt(const QString &data, char key)
  101. {
  102. //采用异或加密,也可以自行更改算法
  103. QByteArray buffer = data.toLatin1();
  104. int size = buffer.size();
  105. for (int i = ; i < size; i++) {
  106. buffer[i] = buffer.at(i) ^ key;
  107. }
  108.  
  109. return QLatin1String(buffer);
  110. }
  111.  
  112. bool AppKey::checkCount(int count)
  113. {
  114. if (keyUseCount) {
  115. if (count >= keyCount) {
  116. QMessageBox::critical(, "错误", "设备数量超过限制,请联系供应商更新注册码!");
  117. return false;
  118. }
  119. }
  120.  
  121. return true;
  122. }

Qt编写密钥生成器+使用demo(开源)的更多相关文章

  1. 年底奉献-QT编写视频监管平台(开源)

    忙忙碌碌又是一年,算算自己毕业四年半,一直在现在这家公司做研发外加总经理助理,研发起初用的VB.NET,而后全面转为C#,最后又全面转为QT,都是由于项目需要,算下来自己搞QT编程也已经四年了,201 ...

  2. Qt编写软件运行时间记录(开源)

    在早期开发的软件中,尤其是初学者入门者写的软件,软件运行久了,难免遇到意外崩溃的时候,可是大部分的运行设备可能在现场客户那,需要记住每一次从软件启动后到软件意外关闭前的运行时间,需要记录的信息包括:编 ...

  3. Qt编写网络中转服务器(开源)

    需求1:手机端或者其他端可以对设备进行回控,并查看设备各种运行状态,接收报警推送等.2:同时支持在局域网.广域网.互联网访问,尤其是互联网访问.3:权限控制,给定账号控制授权的设备,并自动拉取设备信息 ...

  4. Qt编写的开源帖子集合(懒人专用)

    回顾自己学习Qt以来九年了,在这九年多时间里面,从本论坛学习不到不少的东西,今天特意整了一下自己开源过的资源的帖子,整理一起方便大家直接跳转下载,不统计不知道,一统计吓一跳,不知不觉开源了这么多代码, ...

  5. Qt编写自定义控件插件开放动态库dll使用(永久免费)

    这套控件陆陆续续完善了四年多,目前共133个控件,除了十几个控件参考网友开源的代码写的,其余全部原创,在发布之初就有打算将动态库开放出来永久免费使用,在控件比较完善的今天抽了半天时间编译了多个qt版本 ...

  6. Qt编写自定义控件5-柱状温度计

    前言 柱状温度计控件,可能是很多人练手控件之一,基本上都是垂直方向展示,底部一个水银柱,中间刻度尺,刻度尺可以在左侧右侧或者两侧都有,自适应分辨率改动,有时候为了美观效果,可能还会整个定时器来实现动画 ...

  7. Qt编写项目作品大全(自定义控件+输入法+大屏电子看板+视频监控+楼宇对讲+气体安全等)

    一.自定义控件大全 (一).控件介绍 超过160个精美控件,涵盖了各种仪表盘.进度条.进度球.指南针.曲线图.标尺.温度计.导航条.导航栏,flatui.高亮按钮.滑动选择器.农历等.远超qwt集成的 ...

  8. Qt编写气体安全管理系统10-数据导出

    一.前言 数据导出一般指导出到excel表格,可能有部分用户还需要导出到pdf,因为pdf基本上不可编辑,防止用户重新编辑导出的数据,excel可能绝大部分用过电脑的人都知道,广为流行,主要就是微软的 ...

  9. Qt编写自定义控件71-圆弧进度条

    一.前言 现在web形式的图表框架非常流行,国产代表就是echart,本人用过几次,三个字屌爆了来形容,非常强大,而且易用性也非常棒,还是开源免费的,使用起来不要太爽,内置的各种图表和仪表盘等非常丰富 ...

随机推荐

  1. 用不上索引的SQL语句

    下面介绍六种建立索引后不起作用的sql语句. 1.使用不等于操作符(<>, !=) SELECT * FROM dept WHERE staff_num <> 1000; × ...

  2. js Jquery字符UrlEncode 编码 C#(asp.net)解码 Server HttpUtility 区别 cookies存中文

    一.Js asp.net 交互Url编码解码 C#(asp.net)编码:HttpUtility.UrlEncode(url) Jquery解码:decodeURIComponent(url); Jq ...

  3. 深入浅出:全面理解SQL Server权限体系

    转自IT168  好文转载存档! [IT168 技术]权限两个字,一个权力,一个限制.在软件领域通俗的解释就是哪些人可以对哪些资源做哪些操作.在SQL Server中,"哪些人", ...

  4. 腾讯游戏设计(tgideas.qq.com)回复处CSRF任意换马甲

    http://tgideas.qq.com GET /cgi-bin/comments/sendreply.cgi?iActivId=1&iSubActivId=215722&iPar ...

  5. vue学习起步,vue环境安装

    vue安装的前提是安装了nodejs 安装淘宝镜像 npm install -g cnpm --registry=https://registry.npm.taobao.org 安装webpack c ...

  6. Win7 共享打印机 “错误:共享无法保存设置”

    原因:windows的后台防火墙服务进程[Windows Firewall{服务描述}.MpsSvc{服务名字}] 关闭了.services.smc 关闭 解决:重启服务 关闭防火墙的功能,通过控制面 ...

  7. QT 实现QGraphicsProxyWidget对象可选择或移动(item管理实现)

    上篇博文<QT QGraphicsProxyWidget对象可选择或移动的一些tricks>介绍了实现QT QGraphicsProxyWidget对象可选择或移动的一些小的第三方技巧,但 ...

  8. jsavascript 面向对象的下拉菜单

    <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/ ...

  9. 【11-13】A股主要指数的市盈率(PE)估值高度

    全指材料(SH000987) - 2018-11-13日,当前值:12.4646,平均值:30.54,中位数:26.09865,当前 接近历史新低.全指材料(SH000987)的历史市盈率PE详情 内 ...

  10. node.js--Less

    摘要: 现在已经有许多站点使用Node.js,所以在Node.js上配置Less环境也是很重要的,下面分享下如何在Node上使用Less开发,前提是你电脑上已经安装node. 安装: 只需要执行下面一 ...