I made a small program which will encrypt my files using xor encryption method.

It work but to encrypt 11MB file it take like 20 mins.

any suggestions on how to make it faster would be nice.

This is the function that encrypt (this is a thread):

publicvoid encrypt()
{
int let = 0;
long length;
this.go = true;
FileStream fopen = new FileStream(this.open, FileMode.Open);
FileStream fsave = new FileStream(this.save, FileMode.OpenOrCreate);
length = fopen.Length;
progressBar.Invoke((MethodInvoker)delegate
{
progressBar.Maximum = Convert.ToInt32(length);
});
while (length > fopen.Position && this.go == true)
{
if (this.password.Length != let)
{
fsave.WriteByte(Convert.ToByte(fopen.ReadByte() ^ this.password[let]));
progressBar.Invoke((MethodInvoker)delegate
{
progressBar.Value++;
});
let++;
}
else
{
let = 0;
}
}
fopen.Dispose();
fopen.Close();
fsave.Dispose();
fsave.Close();
if (this.go == false)
{
File.Delete(this.save);
}
 
}

and this function also decrypts the file you encrypt.

Dani AI

Generated

: the slowdown is almost entirely I/O and per-call overhead, not the XOR itself. was right to flag the UI updates and thread-safety, and and were right to push block-based processing. Below are practical, modern steps that build on those ideas and a compact, ready-to-use pattern.

Use buffered reads/writes (big byte[] buffers) so the runtime issues a few large system calls instead of millions of ReadByte/WriteByte calls. Open FileStreams with a large internal buffer and the SequentialScan hint, process each buffer in memory (XOR the bytes in-place), then write the whole buffer out. Dispose streams with using blocks and make the cancellation flag visible to the worker thread (volatile or a CancellationToken).

Example pattern (C#) — adjust bufferSize to test performance (64KB or 256KB are good starting points):

using (var inFs = new FileStream(src, FileMode.Open, FileAccess.Read, FileShare.Read, 65536, FileOptions.SequentialScan))
using (var outFs = new FileStream(dst, FileMode.Create, FileAccess.Write, FileShare.None, 65536, FileOptions.SequentialScan))
{
    byte[] buf = new byte[65536];
    long position = 0;
    int keyLen = key.Length;
    int read;
    while ((read = inFs.Read(buf, 0, buf.Length)) > 0)
    {
        for (int i = 0; i < read; i++)
            buf[i] ^= key[(position + i) % keyLen];
        outFs.Write(buf, 0, read);
        position += read;
        // update progress occasionally
    }
}

Extra tips: update the UI infrequently (every few percent, every n MB, or on a 100 ms timer) to avoid redraw cost; benchmark with Stopwatch and try a few buffer sizes; antivirus and disk contention can dominate timings. If real security is required, replace XOR with a proper algorithm (AES via the platform crypto classes is recommended) — see the AES docs for guidance (Aes). For very large files or multi-core speedups consider MemoryMappedFile or chunked parallel processing, but only after the simple buffered approach is implemented and measured. For FileStream reference and constructor options see the FileStream docs: FileStream.

Recommended Answers

All 9 Replies

I made a small program which will encrypt my files using xor encryption method.
It work but to encrypt 11MB file it take like 20 mins.
any suggestions on how to make it faster would be nice.
This is the function that encrypt (this is a thread)...

It would help if you didn't update the progress bar for every single byte that is processed... Drawing on the screen takes time, and for an 11MB file, you have to update your progress bar about 11 million times. :surprised If you did this every kilobyte instead (i.e. every 1024th time through the loop), you'd only need to update 11000 times.
Instead of updating every byte, keep a count of how many bytes have been processed and update every kilobyte, like below:

long count = 0;
length = fopen.Length / 1024;
progressBar.Invoke((MethodInvoker)delegate
{
progressBar.Maximum = Convert.ToInt32(length);
});
while (length > fopen.Position && this.go == true)
{
if (this.password.Length != let)
{
fsave.WriteByte(Convert.ToByte(fopen.ReadByte() ^ this.password[let]));
if( count % 1024 == 0 )
{
    progressBar.Invoke((MethodInvoker)delegate
    {
    progressBar.Value++;
    });
}
//more code
}

The percent operator performs a modulo operation; the result of "a % b" is the remainder after a is divided by b. Basically, the output of the expression "count % 1024" will be 0 whenever count is a multiple of 1024.
:idea:Even better than that, perhaps you could work out an algorithm that meant the progress bar was only updated fifty times for each file. I'll leave that problem up to you.

The % operator can also be put to good use here:
Instead of

if (this.password.Length != let)
{
    fsave.WriteByte(Convert.ToByte(fopen.ReadByte() ^ this.password[let]));
    //Progress bar update code
    let++;
}
else
{
let = 0;
}

you can use

while( length > fopen.position && this.go = true )
{
     fsave.WriteByte(Convert.ToByte(fopen.ReadByte() ^ this.password[count % this.password.Length]));
     //Progress bar update code
 }

P.S: Consider this trivial problem: What happens if "" is read by your thread at the same time as another thread sets it? ;)

That helps a little but it does not work on files which are less then a KB.

it speeds up the program but by very little like a minute or 30s difference.

any more suggestions would be nice.

It might have something to do with the way C# handles bitwise operations. Managed code tends to run slower than unmanaged code. Or it could just be your computer's speed. In my experience, encryption is generally a slow process. The encryption program I wrote (it uses a more secure algorithm which I call "random-seed addition") ran rather slowly too.
Anyway, I'm out of ideas. Anyone else?

It would help us if you would paste use the complete source code, otherwise it's hard to recreate your problem (and eventually help you).

sorry for the late reply.

Instead of me copying and pasting my code here, i have put it in a zip file.

I am using microsoft visual c# express and a newb coder so I dont comment my code much.

Ok, i think it should be quicker now, i introduced some cryptor class with own progressbarupdatehandler. There's still some work for you to do though, mainly the way how you get the filepaths from the open/save dialogs.

Thanks,
it is a lot faster, but its gona take me day or two to figure out what the code is doing as there are some new things in it.

That helps a little but it does not work on files which are less then a KB.

Why would you even need a progressbar for a file less than a KB....thats like needing a photo finish for a race where the lead car is a lap up. Unless your encryption is slow enough to the point you will be able to see the progressbar move during 1KB file encryption, this shouldnt be an issue.

~Tyler S. Breton

Hi,

Your problem is reading and writing byte by byte. Instead you should read as big blocks (like 4KB each at least, as NTFS cluster size is this) XOR'em on the memory and write'em back as blocks.

Loren Soth

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.