功能描述
将生成的可执行程序放在指定的文件夹内,双击后将该目录下所有文件包括子文件夹内文件全部加密,再次双击运行后将进行解密。
加密解密实现
主要运用了异或与取反操作,异或:两个值不同为1,相同为0。取反就是将该数的二进制按位变为与原相反的数,即1变为0,0变为1。例如:
程序:
#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include <string>
#include <queue>
#include <windows.h>
#include <string.h>
#define DATASIZE 4096
#define XOR 0xab
#define TEMP_FILE "a_b_c_d.txt" //临时文件
using namespace std;
class EncryptionAndDecrypt
{
public:
EncryptionAndDecrypt()
{
fp_src = nullptr;
fp_tar = nullptr;
memset(file_data, 0, DATASIZE);
file_path = new char[MAX_PATH];
}
~EncryptionAndDecrypt()
{
delete[] file_path;
}
void GetFilePath()
{
char str[MAX_PATH] = { 0 };
GetCurrentDirectory(MAX_PATH, file_path);//将路径存放在file_path中
GetModuleFileName(NULL, str, MAX_PATH);//获取当前可执行程序文件名(绝对路径)
EXE_Path = str;
int pos = EXE_Path.rfind('\\');
EXE_Path = EXE_Path.substr(pos + 1, EXE_Path.size() - pos - 1);//提取可执行程序文件名
findFile(file_path);
}
void findFile(char* pathName)//查找文件
{
char findFileName[MAX_PATH] = { 0 };
sprintf(findFileName, "%s\\*.*", pathName);
WIN32_FIND_DATA findData;
HANDLE hFile = FindFirstFile(findFileName, &findData);
if (INVALID_HANDLE_VALUE == hFile)
{
cout << "没有文件!" << endl;
return;
}
int ret = 1;
char temp[MAX_PATH];
while (ret)
{
if (findData.dwFileAttributes == FILE_ATTRIBUTE_DIRECTORY)//判断是否为文件夹
{
if (findData.cFileName[0] != '.')
{
//进入文件夹中遍历里面的文件
memset(temp, 0, MAX_PATH);//清空数组
sprintf(temp, "%s\\%s", pathName, findData.cFileName);
cout << "文件夹:" << temp << endl;
//遍历文件夹里面的文件
findFile(temp);
}
}
else //是普通文件
{
memset(temp, 0, MAX_PATH);
if ((strstr(findData.cFileName, EXE_Path.c_str()) == NULL) && (strstr(findData.cFileName, TEMP_FILE) == NULL))//将本执行程序文件与临时文件除外
{
sprintf(temp, "%s\\%s", pathName, findData.cFileName);
cout << "文件:" << temp << endl;
file_queue.push(temp);//将文件的绝对路径入队
}
}
//继续找下一个文件,没有找到则退出循环
ret = FindNextFile(hFile, &findData);
}
}
void EncryptionOrDecrypt_File()//加密文件或解密文件
{
while (!file_queue.empty())//判断当前队列中是否有数据
{
FilePath = file_queue.front();//获取队列数据
cout << "开始处理文件:" << FilePath << endl;
GenerateTargetFile();
fp_src = fopen(FilePath.c_str(), "rb");//二进制读原文件
fp_tar = fopen(FilePath_Target.c_str(), "wb");//二进制写临时文件
while (!feof(fp_src))
{
int ret=fread(file_data,1,DATASIZE, fp_src);//从原文件中读取数据
for (int i = 0;i < DATASIZE;i++)
{
file_data[i] = ~(file_data[i] ^ XOR);//将读到的每一个数据进行异或取反
}
fwrite(file_data,1,ret, fp_tar);//将加密或解密后的数据写入临时文件
memset(file_data, 0, ret);
}
DealFile();
file_queue.pop();//出队
}
}
void GenerateTargetFile()//生成一个临时文件
{
int pos = FilePath.rfind('\\');
FilePath_Target = FilePath.substr(0, pos+1);
FilePath_Target.append(TEMP_FILE);
}
void DealFile()//处理掉临时文件
{
fclose(fp_src);
fclose(fp_tar);
remove(FilePath.c_str());//删除原文件
rename(FilePath_Target.c_str(), FilePath.c_str());//将临时文件改名为原文件名
}
private:
char file_data[DATASIZE];//读出数据存储区
string FilePath;//原文件路径
string FilePath_Target;//临时文件路径
string EXE_Path;//可执行程序文件名
FILE *fp_src;//原文件指针
FILE *fp_tar;//临时文件指针
char *file_path;//当前目录路径(绝对路径)
protected:
queue<string> file_queue;//存储所有文件路径的队列
};
int main()
{
EncryptionAndDecrypt EAD;
EAD.GetFilePath();
EAD.EncryptionOrDecrypt_File();
return 0;
}