50k的文件加密花了近1分钟,why?
在网上下了一个des算法加密源码,附带接口(修改成文件操作)如下:
#include "WjcDes.h "
#include "stdio.h "
#include "string.h "
#include "memory.h "
#include "fstream.h "
void main()
{
char key[]={0,2,0,0,9,3,5,1,9,8,0,0,9,1,7},buf[255];
char str[255];
ifstream infile( "source.txt ");//源文件
ofstream outfile1( "encrypt.txt ");//存放加密后的文件
ofstream outfile2( "decrypt.txt ");//存放解密后的文件
while(!infile.eof())
{
infile.getline(str,128, '\n ');
memset(buf, 0, sizeof(buf));
strcpy(buf, str);
Des_Go(buf, buf, sizeof(str), key, sizeof(key), ENCRYPT);//加密函数
outfile1 < < "\n ";
outfile1 < < buf;
Des_Go(buf, buf, sizeof(str), key, sizeof(key), DECRYPT);//解密函数
outfile2 < < "\n ";
outfile2 < < buf;
}
}
请好心人分析一下为什么速度很慢(50k的文件加密花了近一分钟)。如果不是加密算法的问题,文件操作是不是有大的消耗?另外加密后的文件大小是原文件的5到10倍,是不是有问题?解密文件大小和源文件一致。
[解决办法]
infile.getline(str,128, '\n ');
这一句有问题,你应该一次读取文件到内存,在内存里加密,然后把加密好的内容,一次写入文件.
一次读一点,加密一点,再读,再加密,当然很慢了
[解决办法]
while(!infile.eof())
{
infile.getline(str,128, '\n ');
memset(buf, 0, sizeof(buf));
strcpy(buf, str);
Des_Go(buf, buf, sizeof(str), key, sizeof(key), ENCRYPT);//加密函数
outfile1 < < "\n ";
outfile1 < < buf;
Des_Go(buf, buf, sizeof(str), key, sizeof(key), DECRYPT);//解密函数
outfile2 < < "\n ";
outfile2 < < buf;
}
-------------------------
while(!infile.eof()){
int n = infile.getline(str,128, '\n ');
Des_Go(buf,str,n,key,n,ENCRYPT);
buf[n]=0;
outfile1 < < "\n " < <buf;
Des_Go(str,buf,n,key,n,DECRYPT);
str[n]=0;
outfile2 < < "\n " < <str;}
虽然未必好,但是要比原先少些初始化与复制工作(你根本就不知道它复制了多少)。
[解决办法]
buf 设的大一点,为什么一定要用getline呢,用read读啊
[解决办法]
我的DES这么啰嗦,加密500k也是瞬间的事情啊
//====================================
//
//将一个字节的第j位复制到另一个字节的第k位
//@参数src :源字节
//@参数from:源位数
//@参数des :目的字节
//@参数to:目的位数
//====================================
PRIVATE void bitCopy(unsigned char* src,int from,unsigned char* des,int to)
{
unsigned char mask=0x01;
unsigned char temp;
temp=(mask < <from)&*src;
if(from < to) temp = temp < <(to-from);
else temp=temp> > (from-to);//)&(mask < <to);
*des |=temp;
}
//=====================================================
//@param orgKey: input key
//@param newIp: the buffer for permutated key
//@param map:mapping src to des buffer
//@param mapSize: the length of the buffer map in bytes
//=====================================================
PRIVATE void initPermutation(unsigned char* orgKey, int orgKeyLen,unsigned char* newIPKey, int newIPKeyLen,unsigned char* map,size_t mapSize)
{
int from;
int to;
int srcByteID;
int desByteID;
orgKeyLen -=1;
newIPKeyLen -=1;
for(size_t i=0;i <mapSize;i++){
srcByteID = orgKeyLen-((map[i]-1)> > 3);//among which byte;
from=(map[i]-1)%8;//at which bit;
desByteID = newIPKeyLen-(i> > 3);
to=i%8;
bitCopy(orgKey+srcByteID,from,newIPKey+desByteID,to);
}
}
//将输入64位对象分成左右两个部分。
PRIVATE void split2LR(INPUTPAR lInput,INPUTPAR rInput,KEY theKey)
{
/*for(size_t i=0;i <63;i++){
if(i <32) lInput[3-((i> > 3)%4)] = theKey[7-(i> > 3)];
else rInput[3-((i> > 3)%4)] = theKey[7-(i> > 3)];
}*/
memcpy(lInput,theKey,4);
memcpy(rInput,theKey+4,4);
}
//====================================
//
//
//Cipher function:f(R,K)
//====================================
PRIVATE void f(
INPUTPAR rPrev,
KEYN keyn,
unsigned char* eFunction,
SelectionArray selectFunc,
SelectPermutation theP
)
{
int from;
int to;
int srcByteID;
int desByteID;
KEYN elizedR;
INPUTPAR tempR;
//input R is processed by E function,
//buffer elizedR stores the aftermath.
memset(elizedR,0,6);
for(size_t i=0;i <ELength;i++){
srcByteID = 3-((eFunction[i]-1)> > 3);//among which byte;
from=(eFunction[i]-1)%8;//at which bit;
desByteID = 5-(i> > 3);
to=i%8;
bitCopy(
rPrev+srcByteID,//from byte
from,//bit number
elizedR+desByteID,//to byte
to//to bit number
);
}
// elized buffer XORs keyFunc
for(i=0;i <KeyNLength;i++) elizedR[i] ^= keyn[i];
//B blocks are converted by a set of selection functions Ss.
//doSelection(elizedR,selectFunc,rPrev);
for(i=0;i <8;i++)
doSFun(elizedR,rPrev,selectFunc[i],i);
//selected result has to be permuted in accordance with P
memset(tempR,0,4);
for(i=0;i <PLength;i++){
srcByteID = 3-((theP[i]-1)> > 3);//among which byte;
from=(theP[i]-1)%8;//at which bit;
desByteID = 3-(i> > 3);
to=i%8;
bitCopy(
rPrev+srcByteID,//from byte
from,//bit number
tempR+desByteID,//to byte
to//to bit number
);
}
memcpy(rPrev,tempR,4);
}
//selection functions are to interpret input blocks inputBs
PRIVATE void doSFun(KEYN inputBs,INPUTPAR rPrev,Selection sFuncs,BlockNo blockNo)
{
int start = 6*(8-blockNo);
int byteNo;//in which byte the specified bit is located
int shift;// in which bit the specified bit populated
unsigned char sOutput=(unsigned char)0x00;
unsigned char row=0;
unsigned char col=0;
for(int i=0;i <6;i++){
start -= 1;
byteNo = 5- (start> > 3);
shift = start%8;
bitCopy(inputBs+byteNo,shift,&sOutput,5-i);
}
row = ((sOutput&0x20)> > 4)|((sOutput&0x01));
col = ((sOutput&0x1e)> > 1);
if((blockNo%2)==0){
blockNo > > =1;
rPrev[blockNo] &= 0x0f;
rPrev[blockNo] |=(sFuncs[row][col] < <4);
}else{
blockNo > > =1;
rPrev[blockNo] &= 0xf0;
rPrev[blockNo] |=sFuncs[row][col];
}
}
// cihper and decipher function,integerating relevant components
PUBLIC void enCiphering(DATA input,DATA output,INITP initP,
INITP inInitP,CHOICEP1 pChoice1,
CHOICEP2 pChoice2,EFUNC E,SelectionArray sFuncs,
KEY key,CIPHERP cipherP,LSHCTRL lshftCtrl,KEYNSET keyNSet)
{
INPUTPAR lPart;
INPUTPAR rPart;
INPUTPAR templPart;
//INPUTPAR temprPart;
Buffer aBuffer;
/*KEY backOrigKey;
//backup tempKey
memcpy(backOrigKey,key,8);*/
Zero(aBuffer);
//ciphering
initPermutation(input,8,aBuffer,8,initP,64);
memcpy(input,aBuffer,8);
split2LR(lPart,rPart,input);
for(int i=0;i <16;i++){
memcpy(templPart,rPart,4);
f(rPart,keyNSet[i],E,sFuncs,cipherP);
for(int j=0;j <4;j++) rPart[j] ^= lPart[j];
memcpy(lPart,templPart,4);
}
//making preoutput
memcpy(output,rPart,4);
memcpy(output+4,lPart,4);
Zero(aBuffer);
initPermutation(output,8,aBuffer,8,inInitP,64);
memcpy(output,aBuffer,8);
}
PUBLIC void deCiphering(DATA input,DATA output,INITP initP,
INITP inInitP,CHOICEP1 pChoice1,
CHOICEP2 pChoice2,EFUNC E,SelectionArray sFuncs,
KEY key,CIPHERP cipherP,LSHCTRL lshftCtrl,KEYNSET keyNSet)
{
INPUTPAR lPart;
INPUTPAR rPart;
INPUTPAR templPart;
Buffer aBuffer;
/*KEY backOrigKey;
//backup tempKey
memcpy(backOrigKey,key,8);*/
Zero(aBuffer);
//ciphering
initPermutation(input,8,aBuffer,8,initP,64);
memcpy(input,aBuffer,8);
split2LR(lPart,rPart,input);
//============================
for(int i=0;i <16;i++){
memcpy(templPart,rPart,4);
f(rPart,keyNSet[15-i],E,sFuncs,cipherP);
for(int j=0;j <4;j++) rPart[j] ^= lPart[j];
memcpy(lPart,templPart,4);
}
//making preoutput
memcpy(output,rPart,4);
memcpy(output+4,lPart,4);
Zero(aBuffer);
initPermutation(output,8,aBuffer,8,inInitP,64);
memcpy(output,aBuffer,8);
}
PRIVATE void leftShift(unsigned char* object, int size,int bits)
{
int lastIndex = size-1;
unsigned char mask = 0x80;
unsigned char clean_mask=0xff;
mask > > =7-((bits-1) % 8);
clean_mask > > =7-((bits-1) % 8);
unsigned char CR = (object[0] & mask)> > ((bits-1)% 8);
unsigned char CL;
mask =0x80;
for(int i=0;i <lastIndex;i++){
CL = (object[lastIndex-i] &mask) > > 7;
object[lastIndex-i] < <=1;
object[lastIndex-i] |=CR;
CR= CL;
}
object[0] < <=1;
object[0] |=CR;
object[0] &= clean_mask;
}
PRIVATE void splitKey(KEY oldKey,INPUTPAR lKey, INPUTPAR rKey,unsigned char* pChoice1,int choiceSize)
{
memset(lKey,0,4);
memset(rKey,0,4);
initPermutation(oldKey,8,lKey,4,pChoice1,28);
initPermutation(oldKey,8,rKey,4,pChoice1+28,28);
}
PRIVATE void combineKeys(INPUTPAR C,INPUTPAR D,CMBKEY output)
{
unsigned char mask = 0xf0;
unsigned char CR;
memcpy(output,C,sizeof(INPUTPAR));
for(int i=0;i <3;i++){
output[i] < <= 4;
CR = (output[i+1]&mask)> > 4;
output[i] |= CR;
}
output[i] < <=4;//对第3个字节左移4位,这样该字节的最后4位为0
memcpy(output+4,D+1,3);//将D后三个字节拷贝到output[4.5.6]
output[i] |=D[0];//D的第一个字节第四位有数据并入到output[3]低4位。
}
PUBLIC void keyShedule(KEY theInpuKey,KEYNSET keyNSet)
{
INPUTPAR lkN;
INPUTPAR rkN;
CMBKEY tempKey;//input to pChoice2
memset(keyNSet,0,sizeof(KEYNSET));
splitKey(theInpuKey,lkN,rkN,pChoice1,56);
for(int i=0;i <16;i++){
for(int k=0;k <lshftCtrl[i];k++){
leftShift(lkN,4,28);
leftShift(rkN,4,28);
}
combineKeys(lkN,rkN,tempKey);
//memset(keyNSet[i],0,sizeof(KEYN));
initPermutation(tempKey,7,keyNSet[i],6,pChoice2,48);
}
}