前段时间写了一个基于MFC的文件加密器,不过最近彻底把工作转移到了linux系统,就再写了一个基于命令行的文件加密器。一开始我是想用纯C来写的,但在文件的读写上遇到了问题,于是就借用了C++的文件输入输出流。
在加密处理上依旧走最简单的路线,这次甚至没有对输入的密码进行处理,而直接与文件进行异或达到加密目的。也没有对整个文件进行加密,因为那样太浪费时间了,加密大文件时会等到蛋疼。略懂计算机的人都知道,一个文件的文件头包含了很多文件的基本信息,因此,只要把文件头破坏掉,软件就不能正确读取文件信息。我的做法是先用输入的密码与文件头开始进行数十万次的加密处理,剩下的部分再分成数百万份,也就是在每隔百万分之一文件大小的地方进行一次加密。这样在处理大文件的效率就跟上来了,一般数百Mb以上的文件在处理时间上都不会有太大差异,就算配置差一点的电脑,10秒内也应该可以完成。
好了废话不多说,我喜欢开源,喜欢的朋友可以拿去看看,自己很容易修改成自己的东西。高手勿喷,我承认这真的很简单。
下面是代码(单文件,C++编译器可编译)。
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <iostream>
#include <fstream>
#include <unistd.h>
#include <time.h>
using namespace std;
typedef struct tail{
unsigned char head[8];
unsigned char paw[20];
unsigned char tail[8];
}tails;
void printhelpinfo()
{
printf(“参数缺少或不正确!\n使用方法:\n”);
printf(” -h 查看帮助\n”);
printf(” -p [password] 指定密码\n”);
printf(” -f [filepath] 指定完整的文件路径\n”);
}
int main(int argc,char *argv[])
{
int n = argc;
char *com[n];
unsigned long long i,k;
unsigned long long filesize;
unsigned long long count,start,finish;
int blocksize;
char *filepath;
char *password;
char block[128];
int tailsize = sizeof(tails);
unsigned char head[] = “1234567″;
unsigned char tail[] = “1234567″;
tails TAIL,TAILR;
bool isCip = false;
for(i=0;i<8;i++)
{
TAIL.head = head;
TAIL.tail = tail;
}
if(n==1) //没有任何参数,显示帮助信息
{
printhelpinfo();
return 0;
}
for(i = 0 ; i {
com = argv;
}
if(strcmp(com[1],”-h”)==0 && n==2 ) //-h参数,显示帮助信息
{
printhelpinfo();
return 0;
}
if(strcmp(com[1],”-f”)==0)
{
if(n==2)
{
cout<<”缺少参数,可用[-h]查看帮助信息”<<endl;
}
filepath = (char *)malloc(128);
filepath = com[2];
fstream file;
file.open(filepath,ios::in|ios::out|ios::binary);
if(!file)
{
cout<<”文件打开错误!请检查文件是否存在或有读写权限”<<endl;
return 0;
}
file.seekg(0,ios::end);
streampos ps = file.tellg();
filesize = (unsigned long long )ps;
cout<<”文件大小:”<<filesize<<endl;
tailsize = – tailsize;
file.seekg(tailsize,ios::end);
tailsize = -tailsize;
file.read((char *)(&TAILR),tailsize);
cout<<”文件状态:”;
if(strcmp((char *)TAIL.head,(char *)TAILR.head)==0 && strcmp((char *)TAIL.tail,(char *)TAILR.tail)==0 )
cout<<”已加密\n”;
else cout<<”未加密\n”; return 0; } if(strcmp(com[1],”-p”)==0 && n >= 4) //用密码加密文件
{
filepath = (char *)malloc(128);
password = (char *)malloc(128);
filepath = com[3];
password = com[2];
blocksize = strlen(password);
for(i=0;i<blocksize;i++)
{
TAIL.paw = password;
}
start = clock();
fstream file;
file.open(filepath,ios::in|ios::out|ios::binary);
if(!file)
{
cout<<”文件打开错误!请检查文件是否存在或有读写权限”<<endl;
return 0;
}
//检查文件是否加密
tailsize = – tailsize;
file.seekg(tailsize,ios::end);
tailsize = -tailsize;
file.read((char *)(&TAILR),tailsize);
if(strcmp((char *)TAIL.head,(char *)TAILR.head)==0 && strcmp((char *)TAIL.tail,(char *)TAILR.tail)==0 ) //已加密
{
if(strcmp((char *)TAIL.paw,(char *)TAILR.paw) != 0 )
{cout<<”密码不正确!”<<endl;return 0;}
isCip = true;
}
file.seekg(0,ios::end);
streampos ps = file.tellg();
filesize = (unsigned long long )ps;
if(isCip)
filesize -= tailsize;
cout<<”源文件大小:”<<filesize<<endl;
printf(“正在处理文件头…\n”);
count = filesize / blocksize;
for(i = 0 ; i <count; i++) { if(i>500000) break;
file.seekg(blocksize*i,ios::beg);
file.read((char *)block,blocksize);
for(k=0;k<blocksize;k++)
{
block[k] ^= password[k];
}
file.seekp(blocksize*i,ios::beg);
file.write(block,blocksize);
// cout<<file.tellg<<endl;
}
cout<<”正在对文件进行处理…\n”;
i++;
for(;i<count;)
{
file.seekg(blocksize*i,ios::beg);
file.read((char *)block,blocksize);
for(k=0;k<blocksize;k++)
{
block[k] ^= password[k];
}
file.seekp(blocksize*i,ios::beg);
file.write(block,blocksize);
i = i + (filesize/5000000);
}
if(!isCip)
{
file.seekp(0,ios::end);
file.write((char *)(& TAIL),tailsize);
cout<<”加密成功!”<<endl;
}
else
{
truncate(filepath,filesize);
cout<<”文件已解密!”<<endl;
}
finish = clock();
cout<<”用时”<<(finish-start)/1000<<”ms”<<endl;
return 0;
}
printhelpinfo();
return 0;
}
在加密处理上依旧走最简单的路线,这次甚至没有对输入的密码进行处理,而直接与文件进行异或达到加密目的。也没有对整个文件进行加密,因为那样太浪费时间了,加密大文件时会等到蛋疼。略懂计算机的人都知道,一个文件的文件头包含了很多文件的基本信息,因此,只要把文件头破坏掉,软件就不能正确读取文件信息。我的做法是先用输入的密码与文件头开始进行数十万次的加密处理,剩下的部分再分成数百万份,也就是在每隔百万分之一文件大小的地方进行一次加密。这样在处理大文件的效率就跟上来了,一般数百Mb以上的文件在处理时间上都不会有太大差异,就算配置差一点的电脑,10秒内也应该可以完成。
好了废话不多说,我喜欢开源,喜欢的朋友可以拿去看看,自己很容易修改成自己的东西。高手勿喷,我承认这真的很简单。
下面是代码(单文件,C++编译器可编译)。
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <iostream>
#include <fstream>
#include <unistd.h>
#include <time.h>
using namespace std;
typedef struct tail{
unsigned char head[8];
unsigned char paw[20];
unsigned char tail[8];
}tails;
void printhelpinfo()
{
printf(“参数缺少或不正确!\n使用方法:\n”);
printf(” -h 查看帮助\n”);
printf(” -p [password] 指定密码\n”);
printf(” -f [filepath] 指定完整的文件路径\n”);
}
int main(int argc,char *argv[])
{
int n = argc;
char *com[n];
unsigned long long i,k;
unsigned long long filesize;
unsigned long long count,start,finish;
int blocksize;
char *filepath;
char *password;
char block[128];
int tailsize = sizeof(tails);
unsigned char head[] = “1234567″;
unsigned char tail[] = “1234567″;
tails TAIL,TAILR;
bool isCip = false;
for(i=0;i<8;i++)
{
TAIL.head = head;
TAIL.tail = tail;
}
if(n==1) //没有任何参数,显示帮助信息
{
printhelpinfo();
return 0;
}
for(i = 0 ; i {
com = argv;
}
if(strcmp(com[1],”-h”)==0 && n==2 ) //-h参数,显示帮助信息
{
printhelpinfo();
return 0;
}
if(strcmp(com[1],”-f”)==0)
{
if(n==2)
{
cout<<”缺少参数,可用[-h]查看帮助信息”<<endl;
}
filepath = (char *)malloc(128);
filepath = com[2];
fstream file;
file.open(filepath,ios::in|ios::out|ios::binary);
if(!file)
{
cout<<”文件打开错误!请检查文件是否存在或有读写权限”<<endl;
return 0;
}
file.seekg(0,ios::end);
streampos ps = file.tellg();
filesize = (unsigned long long )ps;
cout<<”文件大小:”<<filesize<<endl;
tailsize = – tailsize;
file.seekg(tailsize,ios::end);
tailsize = -tailsize;
file.read((char *)(&TAILR),tailsize);
cout<<”文件状态:”;
if(strcmp((char *)TAIL.head,(char *)TAILR.head)==0 && strcmp((char *)TAIL.tail,(char *)TAILR.tail)==0 )
cout<<”已加密\n”;
else cout<<”未加密\n”; return 0; } if(strcmp(com[1],”-p”)==0 && n >= 4) //用密码加密文件
{
filepath = (char *)malloc(128);
password = (char *)malloc(128);
filepath = com[3];
password = com[2];
blocksize = strlen(password);
for(i=0;i<blocksize;i++)
{
TAIL.paw = password;
}
start = clock();
fstream file;
file.open(filepath,ios::in|ios::out|ios::binary);
if(!file)
{
cout<<”文件打开错误!请检查文件是否存在或有读写权限”<<endl;
return 0;
}
//检查文件是否加密
tailsize = – tailsize;
file.seekg(tailsize,ios::end);
tailsize = -tailsize;
file.read((char *)(&TAILR),tailsize);
if(strcmp((char *)TAIL.head,(char *)TAILR.head)==0 && strcmp((char *)TAIL.tail,(char *)TAILR.tail)==0 ) //已加密
{
if(strcmp((char *)TAIL.paw,(char *)TAILR.paw) != 0 )
{cout<<”密码不正确!”<<endl;return 0;}
isCip = true;
}
file.seekg(0,ios::end);
streampos ps = file.tellg();
filesize = (unsigned long long )ps;
if(isCip)
filesize -= tailsize;
cout<<”源文件大小:”<<filesize<<endl;
printf(“正在处理文件头…\n”);
count = filesize / blocksize;
for(i = 0 ; i <count; i++) { if(i>500000) break;
file.seekg(blocksize*i,ios::beg);
file.read((char *)block,blocksize);
for(k=0;k<blocksize;k++)
{
block[k] ^= password[k];
}
file.seekp(blocksize*i,ios::beg);
file.write(block,blocksize);
// cout<<file.tellg<<endl;
}
cout<<”正在对文件进行处理…\n”;
i++;
for(;i<count;)
{
file.seekg(blocksize*i,ios::beg);
file.read((char *)block,blocksize);
for(k=0;k<blocksize;k++)
{
block[k] ^= password[k];
}
file.seekp(blocksize*i,ios::beg);
file.write(block,blocksize);
i = i + (filesize/5000000);
}
if(!isCip)
{
file.seekp(0,ios::end);
file.write((char *)(& TAIL),tailsize);
cout<<”加密成功!”<<endl;
}
else
{
truncate(filepath,filesize);
cout<<”文件已解密!”<<endl;
}
finish = clock();
cout<<”用时”<<(finish-start)/1000<<”ms”<<endl;
return 0;
}
printhelpinfo();
return 0;
}