QT设置软件使用期限

您所在的位置:网站首页 能设置软件使用时间的软件 QT设置软件使用期限

QT设置软件使用期限

#QT设置软件使用期限| 来源: 网络整理| 查看: 265

一、设计思路 程序启动

每次启动软件时会读取注册文件,若不存在则提示输入激活码,进行注册。若文件存在,则解析文件验证文件合法性,计算剩余使用期限。

程序激活

为了使每个激活码仅对应一个用户(机器),我们的激活码应当绑定设备,因此应包含MAC地址信息。 激活界面,会显示当前的机器码,机器码根据本机MAC地址通过相应算法生成,因此每个用户的机器码都不同。用户将机器码发送给厂商,厂商根据机器码和使用期限生成相应的激活码,发送给用户,用户输入激活码完成注册。注册后会生成注册文件,文件为二进制加密文件,存放注册日期,使用期限等信息,用户无法直接篡改,且若文件缺失需要重新注册。

二、激活码生成端(厂家端) 生成端界面如下

在这里插入图片描述 由一个机器码输入框、一个有效期输入框、一个激活码生成框以及生成按钮组成。 厂家需要输入用户给出的机器码,输入要赋予的有效期限,点击按钮就能生成激活码。 机器码的获取在 验证端(客户端) 中会提及。

(1)密码表

下方为用随机数生成的密码表,建议大家自己重新生成密码表。

uint8_t pwd[256]={23,95,39,51,15,49,18,20,78,45,24,4,74,113,100,123, 0,37,34,121,127,108,25,37,37,56,20,75,34,8,112,87, 19,117,101,4,24,35,82,107,93,51,95,108,28,33,88,6, 23,26,25,65,84,56,62,33,120,1,65,87,47,51,39,43, 78,23,41,43,95,26,76,50,121,96,75,8,13,24,23,115, 40,99,123,72,52,87,5,81,117,115,42,38,59,26,38,94, 105,28,6,87,18,75,93,107,101,62,19,18,7,37,89,73, 23,92,12,59,46,48,59,10,70,7,81,59,43,77,95,107, 72,66,67,59,48,106,126,120,31,80,105,99,127,9,96,72, 70,27,47,67,32,80,33,64,112,56,13,27,10,71,63,63, 100,59,91,8,1,65,9,35,14,90,71,90,123,37,21,47, 16,62,110,69,39,55,75,30,113,122,53,73,22,29,111,29, 114,89,27,85,76,84,52,85,76,62,26,60,109,90,44,21, 20,46,115,108,19,35,58,55,55,78,27,49,12,69,105,74, 109,91,90,108,127,95,76,53,53,112,74,72,79,26,109,102, 21,10,25,68,67,17,29,22,59,80,39,97,120,104,0,109}; (2)生成激活码 QString getActivationCode(QString machineCode,ing yxq)//machineCode机器码,yxq有效期:天 { QString sj=QDate::currentDate().toString("yyMMdd");//当前日期,由此也说明了激活码仅当天有效 //中间为激活码生成算法,不必深究 QString Activation; for(int j=0;j int tempCode2; tempCode2=Activation.mid(4*k+4,4).toInt(nullptr,16)>>tenToBin(sj.mid(4,2).toInt()).mid(k,1).toInt(); Activation2.append(tenToHexL(tempCode2)); } Activation2.append(Activation.mid(0,4)); Activation2.remove("00"); //激活码生成算法 //此处开始为激活码带有有效期信息的部分 QString str_yxq =tenToHexL(yxq+pwd[sj.mid(4,2).toInt()]).remove(0,1); int jy = yxq ^ pwd[sj.mid(4,2).toInt()]; str_yxq.append(tenToHexL(jy).remove(0,1)); Activation2.append(str_yxq); //有效期信息部分 return Activation2 } 三、验证端(客户端) (1)获取机器码 机器码生成方法如下,其中pwd密码表应与生成端相同。 QString getMachineCode() { QString text; //获取非00-00-00-00-00-00的mac地址 QRegExp regmac("00.00.00.00.00.00"); foreach(QNetworkInterface interface,QNetworkInterface::allInterfaces()){ text = interface.hardwareAddress(); if(text.indexOf(regmac)>=0) continue; else break; } //以mac地址为序号获取密码表相应值 QString machineCode; for(int i=0;i QString code = ui->lineEdit->text(); QString tail = code.mid(code.length()-6,6);//code:QString激活码 tail:激活码后六位,包含有效期信息 //验证激活码有效性 QString machineCode = getMachineCode(); QString sj=QDate::currentDate.toString("yyMMdd"); QString Activation; for(int j=0;j int tempCode2; tempCode2=Activation.mid(4*k+4,4).toInt(nullptr,16)>>tenToBin(sj.mid(4,2).toInt()).mid(k,1).toInt(); Activation2.append(tenToHexL(tempCode2)); } Activation2.append(Activation.mid(0,4)); Activation2.remove("00"); if(code.mid(0,code.length()-10)!=Activation2) return ;//激活码无效,可以根据需求设定函数返回值,返回激活失败原因,我这里偷懒就直接在按钮里了 //验证有效期部分 QString tail = code.mid(code.length()-3,3); int h = tail.toInt(nullptr,16); int iyxq = h ^ pwd[sj.mid(4,2).toInt()];//逆解出有效期 QString str_yxq =tenToHexL(iyxq+pwd[sj.mid(4,2).toInt()]).remove(0,1); if(str_yxq!=code.mid(code.length()-6,3)) return ;//激活码无效,有效期部分校验失败 //写注册文件 QFileInfo fileinfo("PassCode.dat"); if(!fileinfo.exists()){ QFile file("PassCode.dat"); file.open(QIODevice::WriteOnly); QDataStream out(&file); QByteArray ba; ba.resize(15); for(int i=0;i QFileInfo fileinfo("PassCode.dat"); if(!fileinfo.exists()){ return 0;//无注册文件,返回有效期0天,执行首次激活流程 } else{ QFile file("PassCode.dat"); file.open(QIODevice::ReadOnly); QDataStream in(&file); QByteArray ba; QDate date; QString code; in >> ba; in >> date; for(int i=0;i file.remove();//若有效期到期,或者检测到用户通过更改当前日期来延长有效期,则删除注册文件 //再次启动后需要执行首次激活 return 0; } return yxq; } } 3.2 激活码验证算法 checkActivationCode int checkActivationCode(QString code, QDate date) { QString machineCode = getMachineCode(); QString sj=date.toString("yyMMdd"); QString Activation; for(int j=0;j int tempCode2; tempCode2=Activation.mid(4*k+4,4).toInt(nullptr,16)>>tenToBin(sj.mid(4,2).toInt()).mid(k,1).toInt(); Activation2.append(tenToHexL(tempCode2)); } Activation2.append(Activation.mid(0,4)); Activation2.remove("00"); if(code.mid(0,code.length()-10)!=Activation2) return 0; QString tail = code.mid(code.length()-3,3); int h = tail.toInt(nullptr,16); int iyxq = h ^ pwd[sj.mid(4,2).toInt()]; QString str_yxq =tenToHexL(iyxq+pwd[sj.mid(4,2).toInt()]).remove(0,1); if(str_yxq!=code.mid(code.length()-6,3)) return 0; else return iyxq; } 四、补充上述代码中缺少的一些函数 QString Widget::tenToHexL(int ten) { QString a="0123456789ABCDEF"; QString res; if(ten>255) { res=a.at(ten/4096); res.append(a.at(ten/256%16)); res.append(a.at(ten/16%16)); res.append(a.at(ten%16)); } else { res="00"; res.append(a.at(ten/16)); res.append(a.at(ten%16)); } return res; } QString Widget::tenToHexS(int ten) { QString s = "0123456789ABCDEF"; QString res; res.append(s.at(ten/16)); res.append(s.at(ten%16)); return res; } QString Widget::tenToBin(int ten) { QString res; for(int i=0;i


【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3