QT防止自研软件被复制的基本操作(二)

参考一

自研软件为了防止被人任意复制传播,需要设置注册使用模式。基本原理:通过计算机的特异性编号,加上自己的编码,使用加密算法算出一个生成码。

一、计算机的特异性编号

硬盘的编号:最后一块硬盘的编号就行(有些计算机可能有多块硬盘);

CPU的编号;

网卡的编号;最后一块网卡的MAC地址就行;

BIOS的编号;

获取系统的安装日期;

1.1 函数示例

#include <QProcess>QString getWMIC(const QString &cmd)
{//获取硬盘的序列号:wmic diskdrive get serialnumber//获取cpu的序列号:wmic cpu get processorid//获取网卡的MAC地址:wmic nicconfig get macaddress//查询BIOS序列号:wmic bios get serialnumber//查询操作系统安装时间:wmic os get installdate//QString cmd="wmic cpu get processorid";QProcess p;p.start(cmd);p.waitForFinished();QString result = QString::fromLocal8Bit(p.readAllStandardOutput());QStringList list = cmd.split(" ");result = result.remove(list.last(), Qt::CaseInsensitive);result = result.replace("\r", "");result = result.replace("\n", "");result = result.simplified();return result;
}

1.2 工程化处理

获取的这些序列号都很长,而且不同windows版本的电脑,wmic命令可能不同,所以需要进行工程化处理。

(1)各类序列号只取最后一块的;

(2)各类序列号只取后4位,但是:MAC地址取后2位,系统安装时间取前8位;

(3)对于无效查询,将其跳过,但是:如果所有的查询都无效,直接禁止使用软件。

1.3 示例代码

//函数:读取计算机硬件信息
QString KeyGen::GetPCMsg(void)
{//获取硬盘的序列号:wmic diskdrive get serialnumberQString tempStr=getWMIC("wmic diskdrive get serialnumber");QString pwd1 = tempStr.right(4); // 截取字符串的右边字符//获取cpu的序列号:wmic cpu get processoridtempStr=getWMIC("wmic cpu get processorid");QString pwd2 = tempStr.right(4); // 截取字符串的右边字符//获取网卡的MAC地址:wmic nicconfig get macaddresstempStr=getWMIC("wmic nicconfig get macaddress");QString pwd3 = tempStr.right(2); // 截取字符串的右边字符//查询BIOS序列号:wmic bios get serialnumbertempStr=getWMIC("wmic bios get serialnumber");QString pwd4 = tempStr.right(4); // 截取字符串的右边字符//查询操作系统安装时间:wmic os get installdatetempStr=getWMIC("wmic os get installdate");QString pwd5 = tempStr.left(8); // 截取字符串的右边字符return pwd1+pwd2+pwd3+pwd4+pwd5;
}

二、加密算法

使用Qt自带的MD5算法。

#include <QCryptographicHash>//加密所需// MD5 加密
QString MD5_encryption(const QString &data)
{QCryptographicHash md5(QCryptographicHash::Md5);    //使用MD5加密md5.addData(data.toUtf8(),data.size());   // 添加数据QByteArray bArry = md5.result();    //获取MD5加密后的密码QString md5_data;md5_data.append(bArry.toHex());return md5_data;
}

三、验证是否注册

验证注册号:读取ini文件,和程序计算的结果进行对比。

3.1 main.cpp文件

#pragma execution_character_set("utf-8")#include "mainwindow.h"
#include <QApplication>
#include "keygen.h"
#include <QMessageBox>int main(int argc, char *argv[])
{QApplication a(argc, argv);MainWindow w;if(KeyGen::verifyKey()){//验证成功w.show();return a.exec();}else{//验证不成功QMessageBox::warning(NULL, "警告","该软件还未注册,请联系软件开发师注册使用!");return 0;}
}

3.2 keygen.h文件

#ifndef KEYGEN_H
#define KEYGEN_H#include <QProcess>//获取计算机信息所需
#include <QCryptographicHash>//加密所需
#include <QDebug>//打印日志所需
#include <QSettings>//读取配置文件所需
#include <QDir>//读取配置文件所需QString getWMIC(const QString &cmd);
// MD5 加密
QString MD5_encryption(const QString &data);class KeyGen
{public:KeyGen();~KeyGen();//函数:读取计算机硬件信息static QString GetPCMsg(void);//函数:生成注册码static QString generateKey(QString);//函数:验证注册码static bool verifyKey();
};//构建函数
KeyGen::KeyGen()
{
}//析构函数
KeyGen::~KeyGen()
{
}//函数:读取计算机硬件信息
QString KeyGen::GetPCMsg(void)
{//获取硬盘的序列号:wmic diskdrive get serialnumberQString tempStr=getWMIC("wmic diskdrive get serialnumber");QString pwd1 = tempStr.right(4); // 截取字符串的右边字符//获取cpu的序列号:wmic cpu get processoridtempStr=getWMIC("wmic cpu get processorid");QString pwd2 = tempStr.right(4); // 截取字符串的右边字符//获取网卡的MAC地址:wmic nicconfig get macaddresstempStr=getWMIC("wmic nicconfig get macaddress");QString pwd3 = tempStr.right(2); // 截取字符串的右边字符//查询BIOS序列号:wmic bios get serialnumbertempStr=getWMIC("wmic bios get serialnumber");QString pwd4 = tempStr.right(4); // 截取字符串的右边字符//查询操作系统安装时间:wmic os get installdatetempStr=getWMIC("wmic os get installdate");QString pwd5 = tempStr.left(8); // 截取字符串的右边字符return pwd1+pwd2+pwd3+pwd4+pwd5;
}//函数:生成注册码
QString KeyGen::generateKey(QString data)
{data="XXXX"+data+"XXXX";return MD5_encryption(data);
}//函数:验证注册码
bool KeyGen::verifyKey()
{//读取注册表文件License.iniQString importfilepath=QDir::currentPath()+"/License.ini";QSettings *mConfigIni = new QSettings(importfilepath, QSettings::IniFormat);QString mKey_Local=mConfigIni->value("Key").toString();qDebug()<<mKey_Local;//读取系统配置并生成注册码QString tempStr=GetPCMsg();QString mKey_Now=generateKey(tempStr).left(8);qDebug()<<mKey_Now;//判断if(mKey_Local==mKey_Now){return true;}else{return false;}
}QString getWMIC(const QString &cmd)
{//获取硬盘的序列号:wmic diskdrive get serialnumber//获取cpu的序列号:wmic cpu get processorid//获取网卡的MAC地址:wmic nicconfig get macaddress//获取主板的序列号:wmic baseboard get serialnumber//查询BIOS序列号:wmic bios get serialnumber//查询操作系统安装时间:wmic os get installdate//QString cmd="wmic cpu get processorid";QProcess p;p.start(cmd);p.waitForFinished();QString result = QString::fromLocal8Bit(p.readAllStandardOutput());QStringList list = cmd.split(" ");result = result.remove(list.last(), Qt::CaseInsensitive);result = result.replace("\r", "");result = result.replace("\n", "");result = result.simplified();return result;
}// MD5 加密
QString MD5_encryption(const QString &data)
{QCryptographicHash md5(QCryptographicHash::Md5);    //使用MD5加密md5.addData(data.toUtf8(),data.size());   // 添加数据QByteArray bArry = md5.result();    //获取MD5加密后的密码QString md5_data;md5_data.append(bArry.toHex());return md5_data;
}#endif // KEYGEN_H

四、注册机

void MainWindow::on_pushButton_clicked()
{QString tempStr=ui->lineEdit->text();if(tempStr!=NULL){ui->lineEdit_2->setText(KeyGen::generateKey(tempStr).left(11));}
}

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

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

相关文章

【简单讲解下npm常用命令】

&#x1f308;个人主页: 程序员不想敲代码啊 &#x1f3c6;CSDN优质创作者&#xff0c;CSDN实力新星&#xff0c;CSDN博客专家 &#x1f44d;点赞⭐评论⭐收藏 &#x1f91d;希望本文对您有所裨益&#xff0c;如有不足之处&#xff0c;欢迎在评论区提出指正&#xff0c;让我们共…

JavaScript 中的 Class 类

&#x1f525; 引言 在ECMAScript 2015&#xff08;ES6&#xff09;中&#xff0c;class 关键字被引入&#xff0c;为JavaScript带来了一种更接近传统面向对象语言的语法糖。类是创建对象的模板&#xff0c;它们封装了数据&#xff08;属性&#xff09;和行为&#xff08;方法&…

YOLO自研模块:多尺度轻量化卷积模块

目录 一、原理 二、代码 三、配置文件 一、原理 不同大小的卷积核,提取目标特征的特征尺度不同,所以通过使用不同大小卷积核的卷积来提取特征就可以保证获取到目标的多尺度特征。 借鉴YOLOv8中,将通道数进行划分的操作,在卷积的输入过程中为了减小参数量,将输入通道数…

计算机的翻译(编译和链接)过程

&#x1f381;个人主页&#xff1a;我们的五年 &#x1f50d;系列专栏&#xff1a;C语言基本概念 &#x1f337;追光的人&#xff0c;终会万丈光芒 &#x1f389;欢迎大家点赞&#x1f44d;评论&#x1f4dd;收藏⭐文章 目录 &#x1f697;1.翻译环境和运行环境&#xff1…

生信小知识 | 如何快速确定一个物种某一个基因家族全部基因数目

公众号&#xff1a;生信漫谈&#xff0c;获取最新科研信息&#xff01; 生信小知识 | 如何快速确定一个物种某一个基因家族全部基因数目https://mp.weixin.qq.com/s?__bizMzkwNjQyNTUwMw&mid2247486827&idx1&sn9fea85f8d28af3e02570235936a1f535&chksmc0e9e8…

io流,字节流概述

io流概述 io流&#xff1a;输入输出流读写数据的 i 指Input&#xff0c;称为输入流:负责把数据读到内存中去 o指Output&#xff0c;称为输出流:负责写数据出去 io流的分类 按流的方向分为: 输入流和输出流。 按流中数据的最小单位&#xff0c; 分为:字节流&#xff08;适合操作…

展开说说:Android Fragment完全解析-卷三

本文章分析了Fragment的管理器FragmentManager、事务FragmentTransaction 、以及完整的声明周期和动态加载Fragment的原理解析。 1、Fragment管理器 FragmentManager 类负责在应用的 fragment 上执行一些操作&#xff0c;如添加、移除或替换操作&#xff0c;以及将操作添加到…

c#学习基础2

四、复杂数据类型--结构体 1.基本概念 、2.基本语法 结构体一般写在namespace语句块中&#xff1b; 结构体关键字 struct 3.实例 4.结构体的使用 5.访问修饰符 6.结构体的构造函数 7.总结 五、排序初探 1&#xff09;冒泡排序 1.排序的基本概念 2.冒泡排序的基本原理 两…

西班牙语语法名词的复数形式,柯桥西班牙语培训

&#xff08;2&#xff09;后面加-es • 以辅音结尾的名词。例如&#xff1a; el seor - los seores 先生 la ciudad - las ciudades 城市 • 以-y 结尾的名词。例如&#xff1a; el rey - los reyes 国王 la ley - las leyes 法律 • 以-z 结尾的名词&#xff0c;将词尾…

【Linux】学习笔记

文章目录 [toc]第一章&#xff1a;基础篇01|课程介绍02|内容综述03|什么是Linux04|Linux的内核版本及常见发行版内核版本发行版本Red Hat Enterprise LinuxFedoraCentOSDebianUbuntu 05|安装VirtualBox虚拟机VirtualBox下载url 06|在虚拟机中安装Linux系统Linux安装镜像下载 07…

数据库(MySQL)—— 多表查询

数据库&#xff08;MySQL&#xff09;—— 多表查询 多表关系一对多多对多一对一多表查询概述数据准备查询形式笛卡尔积 分类连接查询内连接外连接左外连接右外连接 自连接联合查询 今天我们来进入MySQL中一个非常重要的部分&#xff1a;多表查询&#xff1a; 多表关系 多表关…

从零开始学AI绘画,万字Stable Diffusion终极教程(四)

【第4期】图生图 欢迎来到SD的终极教程&#xff0c;这是我们的第四节课 这套课程分为六节课&#xff0c;会系统性的介绍sd的全部功能&#xff0c;让你打下坚实牢靠的基础 1.SD入门 2.关键词 3.Lora模型 4.图生图 5.controlnet 6.知识补充 在前面的课程中&#xff0c;我…

主机win10,VMware 装了ubuntu,ubuntu传文件到主机

亲测可用&#xff0c;1分钟搞定&#xff0c;不能用你打死我 使用 FileZilla 工具互传 FileZilla是一款免费的工具&#xff0c;是基于 FTP 协议进行文件互传的&#xff0c;在传输过程中我们的ubuntu是作为服务器&#xff0c; FileZilla 工具则是作为客户端。 1 ubuntu安装 FTP…

【力扣】203、环形链表 II

142. 环形链表 II 要解决这道题&#xff0c;首先需要对问题进行拆解&#xff1a; 确定链表是否存在环确定环的入口点 如何判断是否存在环呢&#xff1f;这个比较容易想到&#xff0c;使用快慢指针即可判断链表是否存在环。我们定义两个指针&#xff1a; ListNode slow head…

容器组_配置初始化容器

&#x1f4d5;作者简介&#xff1a; 过去日记&#xff0c;致力于Java、GoLang,Rust等多种编程语言&#xff0c;热爱技术&#xff0c;喜欢游戏的博主。 &#x1f4d8;相关专栏Rust初阶教程、go语言基础系列、spring教程等&#xff0c;大家有兴趣的可以看一看 &#x1f4d9;Jav…

SSM整合-前后端分离-项目环境搭建 (上)

整合SSM 项目基础环境搭建项目介绍创建项目项目全局配置web.xmlSpringMVC配置配置Spring和MyBatis, 并完成整合创建表, 使用逆向工程生成Bean, XxxMapper和XxxMapper.xml注意事项和细节说明 实现功能01-搭建Vue前端工程需求分析/图解代码实现搭建Vue前端工程vue3项目目录结构梳…

服务网关GateWay原理

文章目录 自动装配核心类GatewayAutoConfigurationDispatcherHandler请求处理阶段apply方法httpHandler#handle方法WebHandler#handle方法DispatchHanlder#handle方法第一步 getHandler获取请求映射第二步 invokeHandler 请求适配第三步 handleResult请求处理总结 上一篇博文我…

Gitea 上传用户签名

在 Gitea 的用户管理部分&#xff0c;有一个 SSH 和 GPG 的选项。 单击这个选项&#xff0c;可以在选项上添加 Key。 Key 的来源 如是 Windows 的用户&#xff0c;可以选择 Kleopatra 这个软件。 通过这个软件生成的 Key 的界面中有一个导出功能。 单击这个导出&#xff0c;…

OpenWRT有线桥接部署教程

前言 之前咱们讲到OpenWRT部署WAN实现PPPoE拨号上网和自动获取IP模式上网的办法&#xff1a; OpenWRT设置PPPoE拨号教程 OpenWRT设置自动获取IP&#xff0c;作为二级路由器 这一次&#xff0c;咱们尝试用OpenWRT有线桥接上一级路由器的教程。 可能有小伙伴敏锐地发现了&am…

【JVM】GC调优(优化JVM参数)、性能调优

GC调优 GC调优的主要目标是避免由垃圾回收引起程序性能下降。 GC调优的核心指标 垃圾回收吞吐量&#xff1a;执行用户代码时间/&#xff08;执行用户代码时间 GC时间&#xff09;延迟&#xff1a;GC延迟 业务执行时间内存使用量 GC调优步骤 发现问题&#xff1a;通过监控…