Using Multithreading to encrypt a file

My problem sounds like this:

I have to create a program that encrypts a file by taking each byte and increment it.
The problem is that the program should use multithreading to do the actual encrypting. The number of threads is variable, the user enters them in a Edit Control, and those “x” number of threads, simultaneously must encrypt the file.

What I’ve done so far is that I opened the file in binary mode and encrypt it by incrementing each byte in the file. So far so good, but now I can’t figure out how to create those threads and how should they encrypt the file simultaneously … a little help would be awesome.

Here is the code I done so far: when the user pushes the Ok button (the file has been selected by the user in a previous step), the selected file is encrypted

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
void CEncryptorView::OnBnClickedOk()
{ 
  	CString strControlText;    
	CWnd* pWnd = GetDlgItem(IDC_FILE);
	pWnd->GetWindowText(_T(strControlText));  

	char buf[255];
	
	//open the selected file for encryption
	ifstream fp_in(strControlText, ios_base::binary | ios_base::in);

	unsigned int cntr = 0; //defining a controll variable;
	if(!fp_in)
	{
		++cntr;
		MessageBox("The selected file couldn't be open for reading");
	}
	ofstream fp_out("temp.txt",	ios_base::binary | ios_base::out);
	if(!fp_out)
	{
		++cntr;
		MessageBox("\tThe temp file couldn't be created \n(check you access privileges for default destination!)");
	}

	//encrypting the file, taking each byte in the file and increment it
	if ( fp_in && fp_out )
	{
		char ch;
		while ( fp_in.get ( ch ) )
		  fp_out.put ( ++ch );
	}
	else
		++cntr;

	fp_in.close();
	fp_in.clear();
	fp_out.close();
	fp_out.clear();

	//copying (replacing) the encrypted temp file into the original file, and deleting the tempoarary one
	ifstream fs_in("temp.txt", ios_base::binary | ios_base::in);
	if(!fs_in)
	{
		++cntr;
		MessageBox("An error occured and the encryption failed");
	}
	ofstream fs_out(strControlText,	ios_base::binary | ios_base::out);
	if(!fs_out)
	{
		++cntr;
		MessageBox("An error occured and the encryption failed");
	}

	if ( fs_in && fs_out )
	{
		char ch;
		while ( fs_in.get ( ch ) )
		  fs_out.put ( ch );
	}
	else
		++cntr;

	fs_in.close();
	fs_in.clear();
	fs_out.close();
	fs_out.clear();

	//delete the temp file
	CString fileToDelete("temp.txt");
	if(remove(fileToDelete) == 0 && cntr == 0)
		MessageBox("The file has ben encrypted successfully");
	else
		MessageBox("An error occured and the encryption failed");
}


Thank you!
I would split it up into sections and have each thread encrypt their section, then re-combine them all at the end.
Yes, and how do i do that? :)
I don't think that encrypting of one file should be concurrently, because in this case you have to synchronize reading/writing from/to files and streams. And as I think in this case you will create some treads, but your treads will not work concurrently. But you can very easy to encrypt some files simultaneously and in this case it will be very useful.
I use tbb library from Intel
http://www.threadingbuildingblocks.org/


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50

#include "tbb/blocked_range.h"
#include "tbb/parallel_for.h"
#include <vector>
#include <string>
#include <algorithm>

using namespace tbb;

typedef std::vector <std::string> Container;
typedef Container::iterator Iterator;


class ApplyFoo{
public:
    void operator()(const blocked_range<size_t>& r)const{
        for( size_t i=r.begin(); i!=r.end( ); ++i )
            encrypt(m_files[i]);///your code from previous post, where m_files[i] - it's a name of file
    }
    ApplyFoo(const Container &files) {
     m_files.reserve(files.size());
      std::copy(files.begin(), files.end(), files.begin());}
private:
    Container m_files;
};


class Widget
{
public:
    void onOkBtn();
private:
    Container m_selectedFiles;
};


void Widget::onOkBtn()
{
    parallel_for(blocked_range<size_t>(0, m_selectedFiles.size()), ApplyFoo(m_selectedFiles), auto_partitioner());
}

#include "tbb/task_scheduler_init.h"

int main(int argc, char* argv[]){
    task_scheduler_init init;//requred
    ...
    return 0;
}

Last edited on
Topic archived. No new replies allowed.