C++实现的一个加密文件的程序

近来写了一个有关加密文本的加密程序,基本原理是将文件中所有字节和指定的密码逐字节进行异或,一般文件内容远远长于密码,那么可以扩展密码为:123456123456…这种循环的形式,直到和原文件相同的长度。这样所有文件的内容对被密码加密了,而且由于异或的特性,只需要再执行一下加密的过程,原文件内容就可以被恢复。

下面写一下实现的具体功能,主要函数和效果:

程序可以将程序文件所在文件夹以及子文件夹下,所有后缀为txt和docx的文件进行加密,加密文件后缀变为txtenc,docxenc如果存在需要加密的文件则进行加密(加密文件和未加密文件都在文件夹下时也进行加密),如果所有txt和docx文件都是加密文件,那就通过像用户询问密码来确认是否解密。

vector<string> file_set;

这里定义了一个字符串数组,来存储文件夹下所有满足要求的文件名。

void handle_all_file(string path, vector<string> &file_set)
{
    long hFile = 0;
    struct _finddata_t fileInfo;
    string pathName;
    if((hFile = _findfirst(pathName.assign(path).append("\\*").c_str(), &fileInfo)) == -1) return ;
    do{
        if( strcmp(fileInfo.name,"..") && strcmp(fileInfo.name,".") && fileInfo.attrib==_A_SUBDIR )
            handle_all_file(path+"\\"+fileInfo.name, file_set);
        if (compare_file_name(fileInfo.name, ".txt") || compare_file_name(fileInfo.name, ".docx"))
        {
            encry = true;
            file_set.push_back(path+"\\"+fileInfo.name);
        }else if(compare_file_name(fileInfo.name, ".txtenc") || compare_file_name(fileInfo.name, ".docxenc")){
            file_set.push_back(path+"\\"+fileInfo.name);
        }
    }while(_findnext(hFile, &fileInfo)==0);
    _findclose(hFile);
    return;
}

这里通过结构体_finddata_t来列出所有文件名,它的使用参考了

https://blog.csdn.net/godop/article/details/81080835

compare_file_name是对文件名后缀简单判断,存在符合要求的未加密文件时,让一个全局bool变量encry赋予值true,用于判断执行加密过程还是解密。这个函数将加密文件和未加密文件都挑选出来,所以后继需要根据encry的值判断是对加密文件解密还是对未加密文件加密。

void encry_deencry(vector<string> &file)
{
    if(!encry)
    {
        cout<<"please input password:"<<endl;
        char tempkey[10] = {0};
        cin>>tempkey;
        if(strcmp(tempkey, key) != 0)
            return;
        else{
            cout << "Right!" << endl;
        }
    }
    for(vector<string>::iterator filei=file.begin(); filei != file.end(); ++filei)
    {
        string filej = *filei;
        if(encry && (compare_file_name(filej.c_str(), ".txt"))||(compare_file_name(filej.c_str(), ".docx")))
            handle_one_file(filej);
        if((!encry) && (compare_file_name(filej.c_str(), ".txtenc"))||(compare_file_name(filej.c_str(), ".docxenc")))
            handle_one_file(filej);
    }
}

这个函数是询问密码判断密码是否正确,再度挑选出合适的文件,进行处理。

int handle_one_file(string path)
{
    cout << path <<endl;
    string path1, path2;
    if(encry)
    {
        path1 = path;
        path2 = path+"enc";
    }else
    {
        path1 = path;
        path2 = path1.substr(0, path1.length()-3);
    }
    cout << path1 << "------" << path2 << endl;
    FILE *f = fopen(path1.c_str(), "rb");
    FILE *fw = fopen(path2.c_str(), "wb");
    const int buffer_size = 1024;
    int read_size = 0;
    char buffer[1024+1] = {0};

    int i;

    memset(buffer, 0, buffer_size+1);
    while (read_size = fread(buffer, sizeof (char), buffer_size, f)) {
        for(i = 0; i<read_size; i++){
            buffer[i] ^= key[i%strlen(key)];
        }
        fwrite(buffer, sizeof (char), read_size, fw);
    }
    fclose(f);
    fclose(fw);
    remove(path1.c_str());
    return 0;
}

通过C语言的fopen,fread,fwrite,读出文件然后通过key[i%strlen(key)]循环地用密码取异或原始文件内容。

效果如下:
C++实现的一个加密文件的程序_第1张图片C++实现的一个加密文件的程序_第2张图片
C++实现的一个加密文件的程序_第3张图片

完整代码如下:

#include 
#include 
#include
#include
#include
#include
#include
using namespace std;

char key[] = "123456";

bool encry = false;

bool compare_file_name(const char *s, char *den)
{
    return strrchr(s, '.')&&(strcmp(strrchr(s, '.'), den)==0);
}

int handle_one_file(string path)
{
    cout << path <<endl;
    string path1, path2;
    if(encry)
    {
        path1 = path;
        path2 = path+"enc";
    }else
    {
        path1 = path;
        path2 = path1.substr(0, path1.length()-3);
    }
    cout << path1 << "------" << path2 << endl;
    FILE *f = fopen(path1.c_str(), "rb");
    FILE *fw = fopen(path2.c_str(), "wb");
    const int buffer_size = 1024;
    int read_size = 0;
    char buffer[1024+1] = {0};

    int i;

    memset(buffer, 0, buffer_size+1);
    while (read_size = fread(buffer, sizeof (char), buffer_size, f)) {
        for(i = 0; i<read_size; i++){
            buffer[i] ^= key[i%strlen(key)];
        }
        fwrite(buffer, sizeof (char), read_size, fw);
    }
    fclose(f);
    fclose(fw);
    remove(path1.c_str());
    return 0;
}

void encry_deencry(vector<string> &file)
{
    if(!encry)
    {
        cout<<"please input password:"<<endl;
        char tempkey[10] = {0};
        cin>>tempkey;
        if(strcmp(tempkey, key) != 0)
            return;
        else{
            cout << "Right!" << endl;
        }
    }
    for(vector<string>::iterator filei=file.begin(); filei != file.end(); ++filei)
    {
        string filej = *filei;
        if(encry && (compare_file_name(filej.c_str(), ".txt"))||(compare_file_name(filej.c_str(), ".docx")))
            handle_one_file(filej);
        if((!encry) && (compare_file_name(filej.c_str(), ".txtenc"))||(compare_file_name(filej.c_str(), ".docxenc")))
            handle_one_file(filej);
    }
}


void handle_all_file(string path, vector<string> &file_set)
{
    long hFile = 0;
    struct _finddata_t fileInfo;
    string pathName;
    if((hFile = _findfirst(pathName.assign(path).append("\\*").c_str(), &fileInfo)) == -1) return ;
    do{
        if( strcmp(fileInfo.name,"..") && strcmp(fileInfo.name,".") && fileInfo.attrib==_A_SUBDIR )
            handle_all_file(path+"\\"+fileInfo.name, file_set);
        if (compare_file_name(fileInfo.name, ".txt") || compare_file_name(fileInfo.name, ".docx"))
        {
            encry = true;
            file_set.push_back(path+"\\"+fileInfo.name);
        }else if(compare_file_name(fileInfo.name, ".txtenc") || compare_file_name(fileInfo.name, ".docxenc")){
            file_set.push_back(path+"\\"+fileInfo.name);
        }
    }while(_findnext(hFile, &fileInfo)==0);
    _findclose(hFile);
    return;
}


int main()
{
    vector<string> file_set;

    handle_all_file(".", file_set);
    encry_deencry(file_set);
    return 0;
}


你可能感兴趣的:(C)