Vignere Cipher

Hello Guys,

Not sure if I've advanced past beginner yet so I'll post this here, I'm having some problems with my Vignere Cipher, it is only reading the first 4 chars in my array and encoding them. The test expression MAC'S RULE with key APPLE should become MPR'D VUAT, but its only coming up as MPR'S RULE, Where have I gone wrong? Excuse all the error checking trying to get myself into a good practice of doing it.

cheers for any help

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
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
vignere.h


void vignere_encrypt(char data[], char key[]);
void vignere_decrypt(char data[], char key[]);


vignere.cpp

#include <iostream>
#include <fstream>
#include "vignere.h"
using namespace std;

void vignere_encrypt(char data[], char key[])
{

	int j = 0;
	for (int i = 0; i < sizeof data; i++)
	{
		if (isalpha(data[i]))
		{
			data[i] += key[j] - 'A';
			if (data[i] > 'Z')
			{
				data[i] += -'Z' + 'A' - 1;
			}
				
		}
		
		if(j + 1 == sizeof key)
		{
			j = 0;
		}
		else
		{
			j++;
		}

	}
}

void vignere_decrypt(char data[], char key[])
{

	int j = 0;
	for (int i = 0; i < sizeof data; i++)
	{
		if (isalpha(data[i]))
		{
			if(data[i] >= key[j])
			{
				data[i] = data[i] - key[j] + 'A';
			}
			else
			{
				data[i] = 'A' + ('Z' - key[j] + data[i] - 'A') + 1;
			}

		}

		if(j + 1 == sizeof key)
		{
			j = 0;
		}
		else
		{
			j++;
		}
	}
}


driver.cpp

#include <iostream>
#include <fstream>
#include <string>
#include "vignere.h"
using namespace std;

int main(int argc, char const *argv[])
{
	string Filein, Fileout;
	ifstream fin;

	const int KeySize = 8;
	const int DataSize = 1024;

	char key[KeySize];
	char select;
	char data[DataSize];

	cout << "Enter File to be read in: ";
	cin >> Filein;

	fin.open(Filein.c_str());

	if(!fin.good())
	{
		cout << "No File Exisits" << endl;
	}
	else
	{
		cout << "File opened" << endl;
		fin.getline(data, DataSize, '\n');
		cout << sizeof data << endl;
		ofstream fout;

		cout << "Enter File to be read out to: ";
		cin >> Fileout;

		fout.open(Fileout.c_str());

		if(!fout.good())
		{
			cout << "File could not be created" << endl;
		}
		else
		{
			cout << "File Created" << endl;

			cout << "Enter Key: ";
			cin >> key;
			cout << key << endl;	
		
			cout << "Would you like to [E]ncrypt or [D]ecrypt the file " << Filein << "?: ";
			cin >> select;
			select = toupper(select);
			cout << select << endl;

			switch(select)
			{
				case 'D':
				{
					cout << "you are decrypting" << endl;
					vignere_decrypt(data, key);
					fout << data << endl;
					break;
				}
				case 'E':
				{
					cout << "you are encrypting" << endl;
					vignere_encrypt(data, key);
					fout << data << endl;
					break;
				}
			}
		}
	}

	return 0;
}
You are using sizeof data as your for loop end condition. That is going to return the size of the pointer to your array which is 4 bytes. Hence the reason you are only getting 4 characters encoded. You need to determine the actual number of characters in your array.
haha good timing I got that about an hour ago, is it possible to determine that within the function without changing its conditions?
This should do it: http://www.cplusplus.com/reference/cstring/strlen/
You might want to store the length values of data and key so you don't have to continually call strlen. Then just refer to those variables (like dataLenth and keyLength)
You could get rid of the for loop entirely and just use a while loop to detect the null terminator. '\0'

1
2
3
4
5
6
7
8
9
10
unsigned i=0;

while(array[i])
{
do stuff

i++;
}

ah wonderful ive tried both, I have run into a problem with extern int though, when compiling it is coming up with:

undefined reference to 'KeyLen'
collect2.exe: error: ld returned 1 exit status

what happened? the DataLen worked fine

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
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
driver .cpp

#include <iostream>
#include <fstream>
#include <string>
#include "vignere.h"
using namespace std;

int main(int argc, char const *argv[])
{
	string Filein, Fileout;
	ifstream fin;

	const int KeySize = 8;
	const int DataSize = 1024;

	char key[KeySize];
	char select;
	char data[DataSize];

	cout << "Enter File to be read in: ";
	cin >> Filein;

	fin.open(Filein.c_str());

	if(!fin.good())
	{
		cout << "No File Exisits" << endl;
	}
	else
	{
		cout << "File opened" << endl;
		fin.getline(data, DataSize, '\n');
		int DataLen = strlen(data);
		cout << DataLen << endl;

		ofstream fout;

		cout << "Enter File to be read out to: ";
		cin >> Fileout;

		fout.open(Fileout.c_str());

		if(!fout.good())
		{
			cout << "File could not be created" << endl;
		}
		else
		{
			cout << "File Created" << endl;

			cout << "Enter Key: ";
			cin >> key;
			int KeyLen = strlen(key);
			cout << KeyLen << endl;
		
			cout << "Would you like to [E]ncrypt or [D]ecrypt the file " << Filein << "?: ";
			cin >> select;
			select = toupper(select);
			cout << select << endl;

			switch(select)
			{
				case 'D':
				{
					cout << "you are decrypting" << endl;
					vignere_decrypt(data, key);
					fout << data << endl;
					break;
				}
				case 'E':
				{
					cout << "you are encrypting" << endl;
					vignere_encrypt(data, key);
					fout << data << endl;
					break;
				}
			}
		}
	}

	return 0;
}

vignere.cpp

#include <iostream>
#include <fstream>
#include <cctype>
#include <string>
#include "vignere.h"
using namespace std;

void vignere_encrypt(char data[], char key[])
{
	//extern int DataLen;
	extern int KeyLen;

	int j = 0;
	unsigned i =0;
	//for (int i = 0; i < sizeof(data); i++)
	while(data[i])
	{
		if(data[i] != '\n')
		{
			if (isalpha(data[i]))
			{
				data[i] += key[j] - 'A';
				if (data[i] > 'Z')
				{
					data[i] += -'Z' + 'A' - 1;
				}

				if(j == '\n' || j == KeyLen)
				{
					j = 0;
				}
				else
				{
					j++;
				}		
			}
		}
		i++;
	}
}

void vignere_decrypt(char data[], char key[])
{

	int j = 0;
	unsigned i = 0;
	//for (int i = 0; i < sizeof data; i++)
	while(data[i])
	{
		if (isalpha(data[i]))
		{
			if(data[i] >= key[j])
			{
				data[i] = data[i] - key[j] + 'A';
			}
			else
			{
				data[i] = 'A' + ('Z' - key[j] + data[i] - 'A') + 1;
			}

		}

		if(j + 1 == sizeof(key))
		{
			j = 0;
		}
		else
		{
			j++;
		}
		i++;
	}
}

Topic archived. No new replies allowed.