目录
1. 异或加解密原理
异或密码(simple XOR cipher)是密码学中的一种简单的加密算法,是指对信息进行异或操作来达到加密和解密的目的。按这种逻辑,文本中的每个字符可以通过与给定的密钥进行按位异或运算来加密;若要解密,只需要将加密后的结果与密钥再次进行按位异或运算即可。
通说点来说,就是一个字符异或一个密钥字符进行加密;解密的时候,则用加密后的字符再次异或密钥字符,便能够还原。
2. 文件的加密流程
- 用二进制读取文件;
- 将文件读到缓冲区SourceBuffer;
- 每次从缓冲区读取一个字符;
- 对读取的字符进行异或加密;
- 加密结果保存到结果缓冲区DesBuffer,循环读取字符,直到文件结束;
- 保存加密文件;
3. 代码实现
3.1 读取文件到内存——C语言
/***************************************
* 函数名称:ReadfileToMem_C
* 函数功能:将文件加载到内存——C语言实现(以二进制方式读取)
* 函数参数:
* v_sourcefile:源文件路径
* v_size: 文件大小
*函数返回值:
* char* 文件内容
****************************************/
char *ReadfileToMem_C(char *v_sourcefile, long &v_size, char *v_pwd)
{
FILE *pFile;
long size;
char *pBuffer;
size_t result;
// 打开文件
pFile = fopen (v_sourcefile, "rb");/* 若要一个byte不漏地读入整个文件,只能采用二进制方式打开 */
if (NULL == pFile)
{
fputs("File error", stderr);
exit(1);
}
// 获取文件大小
fseek(pFile, 0, SEEK_END);
size = ftell(pFile);
rewind(pFile);
// 分配内存
pBuffer = (char*)malloc(sizeof(char) * size);
if (pBuffer == NULL)
{
fputs("Memory error",stderr);
exit(2);
}
// 将文件拷贝到buffer中
result = fread(pBuffer, 1, size, pFile);
if (result != size)
{
fputs("Reading error",stderr);
exit(3);
}
fclose (pFile); // 关闭文件
//free (pBuffer); // 释放内存
// // 传入密钥,则需要解密
// if(NULL != v_pwd)
// {
// char *pwd = v_pwd;
// int j = 0;
// int j0 = 0;
// while(pwd[++j0]);
// for(int i = 0; i < size; ++i)
// {
// pBuffer[i] = (pBuffer[i]^pwd[j>=j0?j=0:j++]);
// }
// }
// 传入密钥,则需要解密
if(NULL != v_pwd)
{
char *pwd = v_pwd;
int pwd_len = strlen(pwd);
for(int i = 0; i < size; ++i)
{
pBuffer[i] ^= pwd[i>=pwd_len ? i%pwd_len : i];
}
}
v_size = size;
return pBuffer;
}
3.2 读取文件到内存——C++
/***************************************
* 函数名称:ReadfileToMen_Cplusplus
* 函数功能:将文件加载到内存——C++实现(以二进制方式读取)
* 函数参数:
* v_sourcefile:源文件路径
* v_size: 文件大小
*函数返回值:
* char* 文件内容
****************************************/
#include <iostream>
#include <fstream>
char *ReadfileToMen_Cplusplus(const char *v_sourcefile, long &v_size, char *v_pwd)
{
std::filebuf *pBuf;
std::ifstream filestr;
long size;
char *pBuffer;
// 读取文件
filestr.open(v_sourcefile, std::ios::binary); // 要读入整个文件,必须采用二进制打开
pBuf = filestr.rdbuf(); // 获取filestr对应buffer对象的指针
// 调用buffer对象方法获取文件大小
size = pBuf->pubseekoff(0, std::ios::end, std::ios::in);
pBuf->pubseekpos(0, std::ios::in);
// 分配内存空间
pBuffer = new char[size];
// 获取文件内容
pBuf->sgetn(pBuffer, size);
pBuffer[size - 1] = '\0';
filestr.close();
// 输出到标准输出
std::cout.write(pBuffer, size);
// // 传入密钥,则需要解密
// if(NULL != v_pwd)
// {
// char *pwd = v_pwd;
// int j = 0;
// int j0 = 0;
// while(pwd[++j0]);
// for(int i = 0; i < size; ++i)
// {
// pBuffer[i] = (pBuffer[i]^pwd[j>=j0?j=0:j++]);
// }
// }
// 传入密钥,则需要解密
if(NULL != v_pwd)
{
char *pwd = v_pwd;
int pwd_len = strlen(pwd);
for(int i = 0; i < size; ++i)
{
pBuffer[i] ^= pwd[i>=pwd_len ? i%pwd_len : i];
}
}
v_size = size;
//delete []pBuffer;
return pBuffer;
}
3.3 文件加解密
/***************************************
* 函数名称:EncryDecryFileByXorkey
* 函数功能:加解密文件
* 函数参数:
* in_fname:需要加密或者解密的文件
* pwd: 加密或者解密秘钥
* out_file
*
****************************************/
void EncryDecryFileByXorkey(char *in_fname, char *pwd,char *out_file)
{
FILE *fp1, *fp2;
register char ch;
int j = 0;
int j0 = 0;
fp1 = fopen(in_fname, "rb");
if(fp1 == NULL)
{
printf("cannot open in-file.\n");
exit(1);/*如果不能打开要加密的文件,便退出程序*/
}
fp2 = fopen(out_file, "wb");
if(fp2 == NULL)
{
printf("cannot open or create out-file.\n");
exit(1);/*如果不能建立加密后的文件,便退出*/
}
while(pwd[++j0]);
ch = fgetc(fp1);
/*加密算法开始*/
while(!feof(fp1))
{
fputc(ch^pwd[j>=j0?j=0:j++], fp2);/*异或后写入fp2文件*/
ch = fgetc(fp1);
}
fclose(fp1);/*关闭源文件*/
fclose(fp2);/*关闭目标文件*/
/*程序结束*/
}