One Time Pad- Encryption program

This is Final Project which i have never covered, i am having hard time, determining where to start, i would greatly appreciate any help i can get.

Write a text‐based program that can encrypt or decrypt a text file
using the “unbreakable” One‐Time Pad cryptosystem. The program should read
a text file that contains only English characters (upper and lower case) and blank
spaces, and generate an encrypted or decrypted file following these rules:
(1) For encryption: For each character p in the unencrypted file, generate a
random number r between 1 and 53. The encrypted character C will be
computed by the formula C = p + r. To do this you will need to enccrypt
characters and blank spaces following exactly this mapping:
‘a’ ‘b’ …   ‘z’ ‘A’ ‘B’ …   ‘Z’ [blank space]
1   2 … 26 27 28 … 52          53
Example: if your random number r is equal to 7, the unencrypted
character ‘z’ will be encrypted to character C = ‘z’ + 7 =  33 = ‘H’. Note
that this formula should wrap around; for example, for r = 6 and p = ‘Y’, C
= ‘Y’ + 6 = 51 + 6 = 4 = ‘d’.  
The generated sequence of random numbers r should be stored in a
separate file which is the secret key to decrypt the encrypted file.
Also, of course, you need to generate an encrypted file containing the
encrypted characters.
To run the program the user should type otp -e <unencrypted_file>
<output_file> <secret_file>, where unencrypted_file is the name of the file
you want to encrypt, output_file is the name of the file you want to give to
the encrypted file, and secret_file is the name of the file that will contain the
generated random numbers which are the key to decrypt output_file at a
later time.
(2) For decryption: For each character C in the encrypted file, read the
corresponding number r from the secret key file generated during
encryption, and compute the unencrypted character p using the formula       
p = C – r.  
Example: if your secret key number for a particular character C is r = 7,
the unencrypted character ‘H’ will be computed using the formula p = 33
– 7 = 26 = ‘z’. Note again that this formula should wrap around; for
example, for r = 6 and C = ‘d’, p = ‘d’ ‐ 6 = 4 ‐ 6 = 51 = ‘Y’.
To run the program the user should type otp -d <encrypted_file>
<output_file> <secret_file>, where encrypted_file is the name of the file
you want to decrypt, output_file is the name of the file you want to give to
the unencrypted file, and secret_file is the name of the file that contains the
generated random numbers which are the key to decrypt the output_file. 
http://www.cplusplus.com/forum/beginner/178348/ is full of useful information, go there and get started. Also, why is your assignment the same as the other guy's? You're both in the same school or something?
i assume so. @DDomjosa
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
#include <stdexcept>
#include <fstream>
#include <string>
#include <algorithm>
#include <stddef.h> 
#include <vector>
#include <cstdlib>
#include <iostream>
#include <sstream>

using namespace std;
using std::ifstream;

struct Code                // Creating a struct which will be used to input the secret_file
{
	int num;              // number type int, accociated the to numbers in secret_file
	char letter;			// accociated letter which corresponding to the given number in the secret_file
};

int main(int argc, char* argv[])
{
	
	ifstream unencrypted;       // input stream unencrypted, associated to the unencrypted file
	ifstream secret;			// input stream secret, associated to the secret file
	ofstream output;			// ouput stream output, associated to the encrypted message which will be saved into the output file.
	vector<Code>inputCode;
	vector<char>inputUn;
	vector<char>C;
	char cLetter;
	int cNum;
	char p;
	Code input; 

	int r=0;
	r= rand()%53+1;					// random number r between 1-53, will be used for encrypting 

	secret.open("secret_file.txt");


	unencrypted.open("unencrypted_file.txt");   
	
while(unencrypted>>p)
{
	inputUn.push_back(p);
}

for(int i=0; i<inputUn.size;i++)
{
	
}
while(secret>>input.letter>>input.num)
{
	inputCode.push_back(input);
}






}
Last edited on
Start with this part.
To run the program the user should type otp -e <unencrypted_file> <output_file> <secret_file>, where unencrypted_file is the name of the file you want to encrypt, output_file is the name of the file you want to give to the encrypted file, and secret_file is the name of the file that will contain the generated random numbers which are the key to decrypt output_file at a later time.


You need to use RAII. Don't declare variables until they're used. On declaration, initialise them.

Assume you have functions separate encrypt and decrypt functions. Don't attempt to do the work inline. That'll allow you write short manageable functions rather than long impenetrable functions.
as

1
2
3
4
5
6
7
8
9
10
void getUncrypted(vector<char>& p, int length)
{
	vector<char>inputUn;
	ifstream unencrypted;    // input stream unencrypted, associated to the unencrypted file
	char p;
	while(unencrypted >>p)
	{
		inputUn.push_back(p);
	}
}
Should i open the files within the function itsself? and declare the variable i need within that function?
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
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
#include <stdexcept>
#include <fstream>
#include <string>
#include <algorithm>
#include <stddef.h> 
#include <vector>
#include <cstdlib>
#include <iostream>
#include <sstream>

using namespace std;
using std::ifstream;

struct Code                // Creating a struct which will be used to input the secret_file
{
	int num;              // number type int, accociated the to numbers in secret_file
	char letter;			// accociated letter which corresponding to the given number in the secret_file
};

const char chmap[] = 
    "abcdefghijklmnopqrstuvwxyz"
    "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
    " ";



void getUnencrypted(vector<char>inputUn, int length)
{
	
	ifstream unencrypted;    // input stream unencrypted, associated to the unencrypted file
	char* p;
	while(unencrypted >> p)
	{
		inputUn.push_back(p);
	}
}

void getSecretFile(vector<Code>inputCo, int length)
{
	Code input;
	ifstream secret;			           // input stream secret, associated to the secret file
	while(secret>>input.letter>>input.num)
	{
		inputCo.push_back(input);
	}
}



char encrypt(char c, int r)
{
	// find the position of the char in the char map
    char* p = std::find(chmap, chmap + sizeof(chmap), p);
    if (p == chmap + sizeof(chmap))
        throw std::domain_error("Input character out of range");

    // find the index of the char
    ptrdiff_t idx = p - chmap;

    // add on the random offset
    idx += r;
    idx = idx % sizeof(chmap);

    return idx;
}

char decrypt(char c, int r)
{

}

int main(int argc, char* argv[])
{
	
	  if (strcmp(argv[1], "-e") == 0)
    {
        std::ifstream unencrypted(argv[2]);
        std::ofstream outputfile(argv[3]);
        std::ifstream secretfile(argv[4]);

        std::string line;
        while (std::getline(unencrypted, line))
        {
            for (size_t i = 0, mx = line.size(); i != mx; ++i)
            {
                int r = 1 + rand() % sizeof(chmap);
                char c = encrypt(line[i], r);
                outputfile << c;
                secretfile >> r;
            }
            outputfile << '\n';    
		}
	  }
}
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
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
#include <stdexcept>
#include <fstream>
#include <string>
#include <algorithm>
#include <stddef.h> 
#include <vector>
#include <cstdlib>
#include <iostream>
#include <sstream>

using namespace std;
using std::ifstream;

struct Code                // Creating a struct which will be used to input the secret_file
{
	int num;              // number type int, accociated the to numbers in secret_file
	char letter;			// accociated letter which corresponding to the given number in the secret_file
};

char chmap[] = 
    "abcdefghijklmnopqrstuvwxyz"
    "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
    " ";



void getUnencrypted(vector<char>inputUn, int length)
{
	
	ifstream unencrypted;    // input stream unencrypted, associated to the unencrypted file
	char* p;
	while(unencrypted >> p)
	{
		inputUn.push_back(p);
	}
}

void getSecretFile(vector<Code>inputCo, int length)
{
	Code input;
	ifstream secret;			           // input stream secret, associated to the secret file
	while(secret>>input.letter>>input.num)
	{
		inputCo.push_back(input);
	}
}



char encrypt(char c, int r)
{
	// find the position of the char in the char map
    char* p = std::find(chmap, chmap + sizeof(chmap), p);
    if (p == chmap + sizeof(chmap))
        throw std::domain_error("Input character out of range");

    // find the index of the char
    ptrdiff_t idx = p - chmap;

    // add on the random offset
    idx += r;
    idx = idx % sizeof(chmap);

    return idx;
}

char decrypt(char8 c, int r)
{
	c = std::find(chmap, chmap + sizeof(chmap), c);
	if (c == chmap + sizeof(chmap))
        throw std::domain_error("Input character out of range");

    // find the index of the char
    ptrdiff_t idx = c - chmap;

    // add on the random offset
    idx -= r;
    idx = idx % sizeof(chmap);

    return idx;
}

void outputMessage(vector<char>output

int main(int argc, char* argv[])
{
	
	  if (strcmp(argv[0], "-e") == 0)
    {
		
		std::ifstream unencrypted(argv[1]);
        std::ofstream outputfile(argv[2]);
        std::ifstream secretfile(argv[3]);

        std::string line;
        while (std::getline(unencrypted, line))
        {
            for (size_t i = 0, mx = line.size(); i != mx; ++i)
            {
                int r = 1 + rand() % sizeof(chmap);
                char c = encrypt(line[i], r);
                outputfile << c;
                secretfile >> r;
            }
            outputfile << '\n';    
		}
	  }
}



This is what i have thus far, i greatly appreciate your help.
Please fix your spaces/tabs, it spoils your indentation when posted as tabs are expanded to 8 spaces.

As you copied my sample, error and all, I'll go over it in detail.

main(), on encryption, reads each line of the unencrypted file into line. Each character in line is sent to encrypt() with a random number of suitable range.

encrypt() looks up c's position in the map of input characters, then increments the position by r, the random number. Mod is used to handle any wrap that occurs.

How do we encode encrypt()?

First we need to find the position of c. STL has find() that we can use. We give a range and the object, and it returns where in the range it is, or not as the case might be.
1
2
3
4
5
6
7
    // find the position of the char in the char map
    const char* p = std::find(chmap, chmap + sizeof(chmap), c);
    if (p == chmap + sizeof(chmap))
        throw std::domain_error("Input character out of range");

    // find the index of the char
    ptrdiff_t idx = p - chmap;

Next, we apply the random interval by moving that position. We just move the pointer along with addition, then use the modulus to handle wrap.
1
2
3
    // add on the random offset
    idx += r;
    idx = idx % sizeof(chmap);


Let me know if you don't (or do) understand this, then we can fix decryption.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
char decrypt(char* c, int r)
{
	c = std::find(chmap, chmap + sizeof(chmap), c);
	if (c == chmap + sizeof(chmap))
        throw std::domain_error("Input character out of range");

    // find the index of the char
    ptrdiff_t idx = c - chmap;

    // add on the random offset
    idx -= r;
    idx = idx % sizeof(chmap);

    return idx;
}


im following, the char array contains all the letters, i assume the secret file suppose is suppose to have the letters from a-Z
It seems you didn't understand my explanation above. There's no point in proceeding if you don't.

You should say what you don't understand, so someone can help.
Last edited on
#include<iostream>
#include<vector>
#include<stdlib.h>
#include <stdexcept>
#include <fstream>
#include <string>
#include <algorithm>
#include <stddef.h>

using namespace std;

void changeuppercase(vector<char>& word, int size)
{
for (int i = 0; i < size; i++)
{
if (word[i] >= 97 && word[i] <= 122)
word[i] -= 32;
}
}
void printtext(vector<char> word, int size)
{
for (int i = 0; i < size; i++)
{
cout << (char)(word[i] + 65);
}
cout << endl;
return;
}
size_t getinput(vector<char>& sen)
{
char b;
while (1)
{
b = getchar();
if (b == '\n')
break;
sen.push_back(b);
}
return sen.size();
}
int main()
{
vector<char> sen;
vector<char> enc_sen;
vector<char> dec_sen;
int *p;
int j;
size_t size;
cout << "Enter Message to Encrypt:";
size = getinput(sen);
changeuppercase(sen, size);
p = (int*)malloc(sen.size() * sizeof(int));
for (j = 0; j < size; j++)
{
p[j] = rand() % 26;
if (sen[j] >= 65 && sen[j] <= 90)
enc_sen.push_back((char)((sen[j] - 65 + p[j]) % 26));
else if (sen[j] >= 97 && sen[j] <= 122)
enc_sen.push_back((char)((sen[j] - 97 + p[j]) % 26));
else
enc_sen.push_back((char)sen[j]);
}
cout << "\nEncoded Message:";
printtext(enc_sen, size);
cout << "\nKey for decryption:\n";
for (j = 0; j < size; j++)
{
cout << (char)(p[j] + 65);
}
cout << endl;
cout << "\nDecrypted Message:";
for (j = 0; j < size; j++)
{
if ((enc_sen[j] - p[j]) < 0)
dec_sen.push_back((char)(enc_sen[j] - p[j] + 26));
else if ((enc_sen[j] - p[j]) >= 0)
dec_sen.push_back((char)(enc_sen[j] - p[j]));
else
dec_sen.push_back((char)enc_sen[j]);
}
printtext(dec_sen, size);
return 0;
}
Topic archived. No new replies allowed.