C++软件试用期检测

测试
cpp 复制代码
#include "TrialCheck.h"
int main(int argc, char*argv[])
{
	TrialCheck ckeck;
	bool isOk = ckeck.isUseful("20200601", "20200705");
	printf("%s", isOk ? "欢迎试用" : "试用期已过,请先注册");
	return 0;
}
输出

试用期已过,请先注册

TrialCheck.h
cpp 复制代码
#pragma once
#include <string>

class TrialCheck
{
public:
	TrialCheck();
	~TrialCheck();

	bool isUseful(const std::string &sStart, const std::string &sEnd);

private:
	bool writeUsdDay(const std::string &sStart, const std::string &sEnd);
	bool _isUseful;
	bool _bChecked;
	std::string _filepath;
};
TrialCheck.cpp
cpp 复制代码
#include "TrialCheck.h"
#include <io.h>
#include <time.h>
#include <fstream>
#include <sstream>
#include <mutex>

#ifdef _WIN32
#pragma warning(disable:4996)  
#endif

#define LEN_LIST 128

std::string int2string(int n)
{
	std::stringstream ss;
	std::string s;
	ss << n;
	ss >> s;
	return s;
}

int string2int(const std::string& s)
{
	return atoi(s.c_str());
}

void swap_byte(char*x, char* y)
{//数据交换
	*x = (*x) ^ (*y);
	*y = (*x) ^ (*y);
	*x = (*x) ^ (*y);
}

void CreateKeylist(const char* key, int Lenkey, char* state)
{//state是生成的密匙序列
	unsigned char x = 0;
	unsigned char y = 0;
	unsigned char counter;

	for (counter = 0; counter < LEN_LIST; counter++)
		state[counter] = counter;

	for (counter = 0; counter < LEN_LIST; counter++)
	{
		y = (key[x] + state[counter] + y) % LEN_LIST;
		swap_byte(&state[counter], &state[y]);
		x = (x + 1) % Lenkey;
	}
}

void CreateCipher(char* buffer, int Lenbuffer, char* state)
{//
	unsigned char x = 0;
	unsigned char y = 0;
	unsigned char x_or = 0;
	int counter;

	for (counter = 0; counter < Lenbuffer; counter++)
	{
		x = (x + 1) % LEN_LIST;
		y = (state[x] + y) % LEN_LIST;
		swap_byte(&state[x], &state[y]);
		x_or = (state[x] + state[y]) % LEN_LIST;
		buffer[counter] ^= state[x_or];
	}
}

void xorEncryptDecrypt(std::string &data, char key)
{
	//采用异或加密	
	int size = data.size();
	for (int i = 0; i < size; i++) {
		data[i] = data[i] ^ key;
	}
}

int getToday()
{
	time_t timep;
	time(&timep);
	char tmp[32];
	strftime(tmp, sizeof(tmp), "%Y%m%d", localtime(&timep));
	return string2int(tmp);
}
std::string keyOut(char sKeyOut[LEN_LIST],int today)
{
	std::string skey = "hympsdk";

	skey.append(int2string(today));
	//
	xorEncryptDecrypt(skey, 100);
	CreateKeylist(skey.c_str(), skey.size(), sKeyOut);

	return skey;
}

void encryptTime(const char* sTime, int nSize,
	char sKeyOutCopy[LEN_LIST], std::string &sEncrypt)
{
	char* sbuffer = new char[nSize];
	memcpy(sbuffer, sTime, nSize*sizeof(char));
	CreateCipher(sbuffer, nSize, sKeyOutCopy);

	sEncrypt.append(std::string(sbuffer,nSize));

	delete[] sbuffer;
}

void decryptTime(const std::string &sKey, const std::string& data, std::string& sOut)
{
	char sKeyOut[LEN_LIST];
	CreateKeylist(sKey.c_str(), sKey.size(), sKeyOut);

	int nSize = data.size();
	char* sbuffer = new char[nSize];
	memcpy(sbuffer, data.c_str(), nSize*sizeof(char));
	CreateCipher(sbuffer, nSize, sKeyOut);

	sOut.append(std::string(sbuffer, nSize));
	delete[] sbuffer;
}

//
TrialCheck::TrialCheck()
{
	_isUseful = true;
	_bChecked = false;
#ifdef _WIN32
	_filepath = "C:/windows/hkey.db";
#else
	_filepath = "/usr/bin/hkey.db";
#endif // _WIN32
}

TrialCheck::~TrialCheck()
{
}

bool TrialCheck::isUseful(const std::string &sStart, const std::string &sEnd)
{
	if (_bChecked)	return _isUseful;

	std::mutex mt;
	mt.lock();
	//文件判断
	if ((_access(_filepath.c_str(), 0)) != -1)
	{
		//读取存储
		std::fstream fin(_filepath);
		std::string sLine;
		int index = 0;
		std::string skey, sLastUsedKey;
		while (getline(fin,sLine))
		{
			if (index == 0)
			{
				skey = sLine;
			}
			else if (index == 1)
			{
				sLastUsedKey = sLine;
			}
			++index;
		}
		fin.close();
		if (skey.empty()&& sLastUsedKey.empty())
		{
			_isUseful = false;
		}
		else
		{
			//判断最后使用日期
			std::string sLastUsedDay;
			decryptTime(skey, sLastUsedKey, sLastUsedDay);
			xorEncryptDecrypt(skey, 100);//key:hympsdk+date
			if (skey.find(sLastUsedDay) != -1)
			{
				int lastUsedDay = string2int(sLastUsedDay);
				int startDay = string2int(sStart);
				int endDay = string2int(sEnd);
				int today = getToday();

				//存储时间(today)在日期内
				_isUseful = (lastUsedDay >= startDay 
					&& lastUsedDay <= endDay && 
					today >= startDay && today<=endDay);
			}
			else
			{
				_isUseful = false;
			}
		}
	}
	
	writeUsdDay(sStart, sEnd);
	mt.unlock();
	_bChecked = true;
	return _isUseful;
}

bool TrialCheck::writeUsdDay(const std::string &sStart, const std::string &sEnd)
{
	char sKeyOut[LEN_LIST];
	int today = getToday();
	std::string skey = keyOut(sKeyOut, today);
	
	int startDay = string2int(sStart);
	int endDay = string2int(sEnd);

	_isUseful = (today >= startDay && today <= endDay);

	std::string sToday = int2string(today);

	std::string sTodayKey;
	encryptTime(sToday.c_str(), sToday.length(), sKeyOut, sTodayKey);
	//写入文件
	std::fstream out;
	out.open(_filepath, std::ios::out | std::ios::binary);
	if (!out.is_open())
	{
		return false;
	}
	out.write(skey.c_str(), skey.size());
	out << '\n';
	out.write(sTodayKey.c_str(), sTodayKey.size());
	out.close();

	return _isUseful;
}

创作不易,小小的支持一下吧!

相关推荐
人才程序员4 分钟前
CSP-J 复赛算法 贪心算法练习
c语言·开发语言·c++·算法·贪心算法·竞赛·csp
阿洵Rain8 分钟前
【C++】内存管理
java·jvm·c++
羑悻的小杀马特8 分钟前
面试题05.08绘制直线问题详解(考察点为位运算符)
c++·算法
三个黄色的小石头11 分钟前
【tower-boot 系列】开源RocketMQ和阿里云rockerMq 4.x和5.x集成 (一)
java·阿里云·开源·rocketmq
大道归简23 分钟前
3.点位管理改造-列表查询——帝可得管理系统
java·spring boot·前端框架·intellij-idea
克鲁德战士29 分钟前
【Nacos 架构 & 原理】服务发现模块之Nacos注册中心服务数据模型
java·架构·服务发现
小安运维日记40 分钟前
Linux云计算 |【第四阶段】RDBMS1-DAY5
linux·运维·服务器·数据库·mysql·云计算
碧海蓝天202240 分钟前
新版双向链表,添加了at, front, back, insert, emplace等为了兼容std.
数据结构·c++·链表
WZF-Sang1 小时前
STL——map和set【map和set的介绍和使用】【multimap和multiset】
开发语言·数据结构·c++·b树·学习·leetcode·visual studio
黑马金牌编程1 小时前
nginx常用的性能优化
运维·服务器·nginx·性能优化