deciphering an unknown shifted caesar cipher text file

Hello every one,
I have spent the past week working on this assignment and i'm hoping to get some help on what I need to do to correct my sift and get it to print out.

the assignment is to open an encrypted file, count the occurrence of each alphabetic character in the file. find the highest occurring letter and use that to find the shift, then apply the sift to the file in order to decipher and then print out the deciphered txt.

sorry for any miss spellings, and thanks for any help you may have


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
#include <fstream>
#include <iostream>
#include <string>

using namespace std;


int main(){

	string word;
	ifstream txt;
	int arr[26] = { 0 };
	char ch;



	//opens the file encrypted.txt
	txt.open("C:/encrypted.txt");
	if (txt.is_open()){             // need to find # of eatch charikter not the # of individual char
		/*while (txt.get(ch)){        // reads char one at a time
		if (isalpha(ch)){			  //checks if it is alphebetikal
		ch = tolower(ch);			  //switches all the char to lower char

		int index = ch - 'a';		  //the 'a' will set your array 0-26
		arr[index]++;				  //this will increas the count for eatch letter on the array
		}
		}*/
		while (!txt.eof()){         //untill you reatch the end of the file ....
			txt >> ch;              //set the content of file txt into char ch
			ch = tolower(ch) - 'a'; //the a will set your array 0-26
			arr[ch]++;              //this will increas the count for eatch letter on the array
		}
	}
	else{							//if the file is not open 
		cout << "hav not found file, will now end program";
		getchar();
		getchar();
		return 0;
	}

	int maxIndex = 0;
	int position;

	for (int i = 0; i < 26; i++)
	{
		if (i == 1)
		{
			maxIndex = arr[i];
			position = 1;
		}
		else if (arr[i] >= maxIndex){
			maxIndex = arr[i];
			position = i;
		}
	}

	// this will calculate  the shift and then shift the char in the txt to the right letters 


	int shift;
	shift = position - 4;

	txt.open("C:/encrypted.txt");

	while (!txt.eof()){
		while (txt.get(ch)){        // reads char one at a time
			if (ch >= 'A' && ch <= 'Z')
			{
				ch = (char)(((ch - shift - 'A' + 26) % 26) + 'A');
			}
			else if (ch >= 'a' && ch <= 'z')
			{
				ch = (char)(((ch - shift - 'a' + 26) % 26) + 'a');
			}
			

		}
	}
	cout << ch;

	//pouse and exit
	getchar();
	getchar();
	return 0;
}
Last edited on
I cleaned up your code, but I don't know how the deciphering works so I'll leave that to you. You'll probably want to re-add your comments.
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
#include <iostream>
#include <fstream>

using namespace std;

int main ( )
{
	ifstream txt ( "C:/encrypted.txt" );
	int index, arr[26] = { 0 };
	char ch;

	if ( txt )
	{
		while ( txt >> ch )
		{
			index = tolower ( ch ) - 'a';
			++arr[ch];
		}

		txt.close ( );
	}

	else
	{
		cout << "File Not Found\n\n";
		return 0;
	}


	int position, maxIndex = 0;

	for ( int i = 0; i < 26; ++i )
	{
		if ( arr[i] > maxIndex )
		{
			maxIndex = arr[i];
			position = i;
		}
	}


	int shift = position - 4;

	txt.open ( "C:/encrypted.txt" );

	while ( txt >> ch )
	{
		if ( isupper ( ch ) )
		{
			ch = ((ch - shift - 'A' + 26) % 26) + 'A';
		}
		else if (ch >= 'a' && ch <= 'z')
		{
			ch = ((ch - shift - 'a' + 26) % 26) + 'a';
		}
	}

	cout << ch;
}
Last edited on
thank you for your help but every time i run the code you had cleaned up it breaks, ill continue to work on it though. :)
On line 30 you have
ch = tolower(ch) - 'a';
What if ch isn't a lower case letter? What if it's upper case, or a space or punctuation mark?

Line 45:
if (i == 1)
What about when i == 0?

On line 60 you have:
shift = position - 4;
I assume this is saying that the the most frequent letter should be 'e'? You should add a comment here.

The calculations look good.

Dave
Ok, so this is what I have now, a made some changes and tried a few things but my output is now a downward arrow. is there any way to get this to print out as a string.

I tried creating a string var and += ch to it both inside and outside the of the final shift loops but I got nothing back.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
	txt.open("C:/encrypted.txt");
	string txtF;
	while (txt >> ch)
	{
		if (isupper(ch))
		{
			ch = ((ch - shift - 'A' + 26) % 26) + 'A';
			txtF += ch;
		}
		else if (ch >= 'a' && ch <= 'z')
		{
			ch = ((ch - shift - 'a' + 26) % 26) + 'a';
			txtF += ch;
		}
		
	}


and

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
	txt.open("C:/encrypted.txt");
	string txtF;
	while (txt >> ch)
	{
		if (isupper(ch))
		{
			ch = ((ch - shift - 'A' + 26) % 26) + 'A';
			
		}
		else if (ch >= 'a' && ch <= 'z')
		{
			ch = ((ch - shift - 'a' + 26) % 26) + 'a';
			
		}
		txtF += ch;
	}



this is it in its entirety
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
#include <fstream>
#include <iostream>
#include <string>

using namespace std;


int main(){

	string word;
	ifstream txt;
	int arr[26] = { 0 };
	char ch;



	//opens the file encrypted.txt
	txt.open("C:/encrypted.txt");
	if (txt.is_open()){						  // need to find # of eatch charikter not the # of individual char
		while (!txt.eof()){					  //untill you reatch the end of the file ....
			txt >> ch;						  //set the content of file txt into char ch
			if (isalpha(ch)){
				ch = tolower(ch) - 'a';       //the a will set your array 0-26
				arr[ch]++;                    //this will increas the count for eatch letter on the array
			}
		}

	}
	else{							          //if the file is not open 
		cout << "hav not found file, will now end program";
		getchar();
		getchar();
		return 0;
	}

	int maxIndex = 0;
	int position =0;

	for (int i = 0; i < 26; i++)
	{

		int position, maxIndex = 0;
		for (int i = 0; i < 26; ++i)
		{
			if (arr[i] > maxIndex)
			{
				maxIndex = arr[i];
				position = i;
			}
		}
	}
	int shift = position - 4;	// becous the highest # in the array is equivelent to e in a decripted file,
								//shift is = to difrence betwean the highest #s lowcation in the array and 'e' whitch address should = 4


				// this will calculate  the shift and then shift the char in the txt to the right letters 
	txt.open("C:/encrypted.txt");
	string txtF;
	while (txt >> ch)
	{
		if (isupper(ch))
		{
			ch = ((ch - shift - 'A' + 26) % 26) + 'A';
			
		}
		else if (ch >= 'a' && ch <= 'z')
		{
			ch = ((ch - shift - 'a' + 26) % 26) + 'a';
			
		}
		
	}

	cout << ch;


	//pouse and exit
	getchar();
	getchar();
	return 0;
}



Ps: thank you both for taking the time to help so far


If the code that reads the input file the first time works then use it again write the output:
1
2
3
4
5
6
7
8
9
10
11
txt.open("C:/encrypted.txt");
if (txt.is_open()){
    while (!txt.eof()){
	txt >> ch;
	if (isupper(ch))	{
	    ch = ((ch - shift - 'A' + 26) % 26) + 'A';
	} else if (islower(ch)) {	// note that I used islower()
	    ch = ((ch - shift - 'a' + 26) % 26) + 'a';
	}
	cout << ch;
}

Actually this code isn't quite right. eof() won't be true until after you try to read past it, so this code will output one extra character. Try this instead:
1
2
3
4
5
6
7
8
9
10
11
12
txt.open("C:/encrypted.txt");
if (txt.is_open()){
    txt >> ch;		// get the first character
    while (!txt.eof()){
	if (isupper(ch))	{
	    ch = ((ch - shift - 'A' + 26) % 26) + 'A';
	} else if (islower(ch)) {	// note that I used islower()
	    ch = ((ch - shift - 'a' + 26) % 26) + 'a';
	}
	cout << ch;
	txt >> ch;	// get the next character
}

If this works, then change the input code to do it the same way.

One more thing: when you're dong reading txt, close it with txt.close(). Do this both times after reading it.
Topic archived. No new replies allowed.