Cipher program - comments welcome

First I would like to say that this is NOT a professional encryption program and it could very very easily be cracked by professionals or someone with a keen desire to crack the code. It simply does not have a strong enough algorithm.

This program is similiar to the Vigenère cipher. The only difference is that instead of cycling a - z, it cycles from ascii 32 (" ") to ascii 126 ("~"). This allows the user up to 95 possible characters to encode and decode.

More information about the Vigenère cipher is available here:
http://en.wikipedia.org/wiki/Vigenère_cipher

Program features:

- Load / Save encrypted data
- Add/modify key phrase at any time without having to re-enter data. The default key is ascii 32 (" ") which is neutral, so crypted text = decrypted text
- Though the save option only saves the crypted text, the user can save with no key and load later choosing to either encrypt or decrypt that text
- Each key/crypted/decrypted message is stored as a class object, thus allowing multiple messages (not implimented in this program but easily possible)

I'm still a newb and I'm looking for comments and suggestions. There are many things I'd like to improve such as the way the file is saved and retrieved. Also just wanted to share as I've been seeing people asking about ciphers so maybe this will be of interest to some.

All are free to copy/modify/redistribute this program. ^^


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
// main.cpp
#include <iostream>
#include "crypter3.h"

int main()
{
	std::string key;
	std::string text;
	std::string filename = "cryptfile.bin";

	std::cout << "\n~ cipher v.3 ~" << std::endl;

	Crypter Crypt; // create object to code/decode
	
	int answer;
	do
	{
		std::cout <<
			"\nChoose an option:\n"
			"0 - exit\n"
			"1 - add key\n"
			"2 - add text\n"
			"3 - encrypt & view\n"
			"4 - decrypt & view\n"
			"5 - load ecrypted\n"
			"6 - save ecrypted\n";

		std::cin >> answer;
		std::cin.get();

		switch (answer)
		{
			case 0:
				std::cout << "\nBye." << std::endl;
				break;
			case 1:
				std::cout << "\nEnter key phrase: " << std::endl;
				getline (std::cin, key);
				Crypt.setKey(key);
				break;
			case 2:
				std::cout << "\nEnter text: " << std::endl;
				getline (std::cin, text);

				// erase previous encrypted/decrypted text
				Crypt.setDecoded(text);
				Crypt.setCoded(text);
				break;
			case 3:
				std::cout << "\nEncoded result:" << std::endl;
				Crypt.encode();
				std::cout << Crypt.viewCoded() << std::endl;
				break;
			case 4:
				std::cout << "\nDecoded result:" << std::endl;
				Crypt.decode();
				std::cout << Crypt.viewDecoded() << std::endl;
				break;
			case 5:
				Crypt.openFile(filename);
				std::cout << "\nLoaded file \"" << filename
				<< "\"." << std::endl;
				Crypt.decode();
				break;
			case 6:
				Crypt.saveFile(filename);
				std::cout << "\nSaved as \"" << filename
				<< "\"." << std::endl;
				break;
			default:
				std::cout << "\nInvalid selection." << std::endl;
		}

	}
	while (answer != 0);

	return 0;
}



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
// crypter3.h
#ifndef CRYPTER3_H
#define CRYPTER3_H

class Crypter
{
private:
	std::string key;
	std::string decoded;
	std::string coded;
public:
	Crypter();
	~Crypter();

	void setKey(std::string newKey);
	void setDecoded(std::string newDecoded);
	void setCoded(std::string newCoded);

	void encode();
	void decode();
	
	std::string viewCoded();
	std::string viewDecoded();
	
	void saveFile(std::string filename);
	void openFile(std::string filename);
};

#endif // CRYPTER3_H 



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
// crypter.cpp
#include <iostream>
#include <fstream>
#include <cstring>
#include "crypter3.h"

Crypter::Crypter()
{
	setKey(" ");	// a " " key is neutral (no change to text)
	setDecoded("");
	setCoded("");
}

Crypter::~Crypter()
{
	
}

void Crypter::setKey(std::string newKey)
{
	key = newKey;
}

void Crypter::setDecoded(std::string newDecoded)
{
	decoded = newDecoded;
}

void Crypter::setCoded(std::string newCoded)
{
	coded = newCoded;
}

void Crypter::encode()
{
	coded = "";
	unsigned int count = 0;

	for (unsigned int i = 0; i < decoded.length(); i++)
	{

		// start at beginning of key when end is reached
		if (count > key.length() - 1)
			count = 0;

		/* add the value of key to decoded minus ascii 32 (" ")
		 * <space> which is neutral. if above ascii 126 ("~"),
		 * loop back to ascii 32 again by subtracting the maximum
		 * unique characters capable of being encoded/decoded,
		 * 95. User can use ascii 32 - ascii 126 for coding. */

		if (int(decoded[i] + key[count] - 32) > '~')
			coded += char(decoded[i] + key[count] - 32 - 95);
		else
			coded += char(decoded[i] + key[count] - 32);

		count++;
	}

}

void Crypter::decode()
{
	decoded = "";
	unsigned int count = 0;

	for (unsigned int i = 0; i < coded.length(); i++)
	{

		// start at beginning of key when end is reached
		if (count > key.length() - 1)
			count = 0;

		/* subtract the value of key to coded plus ascii 32
		 * (" ") <space> which is neutral. if below ascii 32
		 * (" ") then add 95, which is the maximum unique
		 * characters capable of being encoded/decoded */

		if (int(coded[i] - key[count] + 32) < 32)
			decoded += char(coded[i] - key[count] + 32 + 95);
		else
			decoded += char(coded[i] - key[count] + 32);

		count++;
	}

}

std::string Crypter::viewCoded()
{
	return coded;
}

std::string Crypter::viewDecoded()
{
	return decoded;
}

void Crypter::saveFile(std::string filename)
{
	// copy string coded to char * a, to allow saving to file
	char *a = new char[coded.size() + 1];
	a[coded.size()] = 0;
	memcpy(a, coded.c_str(), coded.size());
	
	// check if file opened okay
	std::fstream fbin(filename, std::ios::binary | std::ios::out);
	if (!fbin) {
		std::cout << "Could not open " << filename << std::endl;
	}
	
	// Write data to the file.
	fbin.seekp(0 * coded.size());
	fbin.write(a, coded.size());
	fbin.close();
	
}

void Crypter::openFile(std::string filename)
{
	coded = "";
	decoded = "";
	char a[1];
	
	// check if file opened okay
	std::fstream fbin(filename, std::ios::binary | std::ios::in);
	if (!fbin) {
		std::cout << "Could not open " << filename << std::endl;
	}

	int length = 0;
	
	do
	{

	// read next character in file (next record)
	fbin.seekp(length * 1);
	fbin.read(a, 1);
	
	coded += a[0];
	length++;
		
	}
	while (fbin);

	// remove last repeated character caused by eof
	coded.resize(coded.size() - 1);

	fbin.close();

}


To compile throw all files in same directory and type:
g++ -Wall main3.cpp crypter3.cpp -o crypt


Run the file 'crypt' to start.
Nice work. However, to get it to compile in Visual Studio 2010, I had to #include <string> on both main.cpp and crypter.cpp. <cstring> seems to not work.
I made my own personal encryption program myself not to long ago, its probably total crap but it does what I ask it to and my school cant read anything I encrypt with it unless they have the password to the file, if you want to see the source I'll post it, it was just kinda a hobby program to see if I could do it.

EDIT: also, good work
Last edited on
Nice work. However, to get it to compile in Visual Studio 2010, I had to #include <string> on both main.cpp and crypter.cpp. <cstring> seems to not work.

Thanks for pointing that out. I don't know why that is. :/

I made my own personal encryption program myself not to long ago, its probably total crap but it does what I ask it to and my school cant read anything I encrypt with it unless they have the password to the file, if you want to see the source I'll post it, it was just kinda a hobby program to see if I could do it.

EDIT: also, good work

Yes, please do post it. It would be nice to get some ideas.

Btw, thank you for the replies. I know long posts like this can be a pain to read.
here's the source to my program, sorry for the late reply

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
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
#include<iostream>
#include<fstream>
#include<string>
#include<math.h>
#include<stdlib.h>
#include<conio.h>
#include<limits>

using namespace std;

int main(){

	char opt;
	string pass, passb, passc, fname, fstxt;
	int passp = 0;
	int plen,passl;

	cout<<"n for new file,\no to open an existing file...\n::"<<ends;
	cin>>opt;

	if(!(opt == 'n'|| opt == 'o')){
        cout<<"ERROR: Invalid Answer!\nPress any key to exit..."<<endl;
        getche();
        exit(1);
	}

	if(opt == 'n'){
		while(true){
			cout<<"\nInput the new file's name.\n::"<<ends;
			cin.ignore(numeric_limits<streamsize>::max(), '\n');
			getline(cin, fname);
			cout<<"\nIs \""<<fname<<"\" correct?\n::"<<ends;
			cin>>opt;
			if(opt == 'y'){
				break;
			}
			if(!(opt == 'y' || opt == 'n')){
				cout<<"\nInvalid Answer!"<<endl;
			}
		}
		while(true){
            cout<<"\nPassword protect?\n::"<<ends;
            cin>>opt;
            if(opt == 'y'){
                passp = 1;
                break;
            }
            if(opt == 'n'){
                break;
            }
            if(!(opt == 'y' || opt == 'n')){
                cout<<"\nInvalid Answer: Password cannot be set";
            }
		}
		while(passp == 1){
			cout<<"\nPassword?\n::"<<ends;
			cin>>pass;
			cout<<"\nRe-enter Password\n::"<<ends;
			cin>>passc;
			if(pass == passc){
                break;
			}
			else{
                cout<<"\nThe passwords don't match!\nTry again..."<<endl;
			}
		}
    fname.append(".ett");
    int x;
    x = fname.length();
    char fname2[x];
    for(int b = 0; b <= x; b++){
        fname2[b] = fname[b];
    }
	ofstream outf(fname2);
		if(!outf){
			cout<<"\nERROR:Could not create or open the file \""<<fname<<"\"!\nCheck if the file is write protected..."<<endl;
			cout<<"Press any key to exit..."<<endl;
			getche();
			exit(1);
        }
    if(passp == 1){
        string passb;
        passb = pass;
        passl = pass.length();
        for(int x = 0;x <= passl;x++){
            if(pass[x] != '\0'){
                pass[x]= ((pass[x] + 5) * 2) - 3;
                cout<<pass[x];
            }
        }

        cout<<endl;
        outf.put(passp);
        outf<<pass<<endl;
    }

    if(passp == 0){
        outf.put(passp);
    }

    if(!(passp == 1 || passp == 0)){
        cout<<"\nERROR: Something went wrong...\nPress any key to exit..."<<endl;
        getche();
        exit(1);
    }

    cout<<"\nInput text\n::"<<ends;
    cin.ignore(numeric_limits<streamsize>::max(), '\n');
    getline(cin,fstxt);
    x = fstxt.length();
    passb = passc;
    int  y = passb.length();
    y = y - 1;
    x = x - 1;
    for(int b = 0,c = 0,ud = 0; b <= x; b++){
            fstxt[b] = (fstxt[b] + (passb[c] * 2)) - passb[c];
            cout<<fstxt[b];
            if(c == y){
                ud = 1;
            }
            if(c == 0){
                ud = 0;
            }
            for(;;){
                if(ud == 0 && c < y){
                    c = c + 1;
                }
                if(ud == 1 && c > 0){
                    c = c - 1;
                }
                break;
            }
    }
    while(true){
        cout<<"\nSave?\n::"<<ends;
        cin>>opt;
        if(opt == 'y'){
            outf<<fstxt;
            outf.close();
            break;
        }
        if(opt == 'n'){
            exit(0);
        }
        if(!(opt == 'n' || opt == 'y')){
            cout<<"\nERROR: Invalid Answer!"<<endl;
        }
    }
    cout<<"\nSaved!\nPress any key to exit..."<<endl;
    getche();
    exit(0);
	}

	if(opt == 'o'){
        cout<<"File name?\n::"<<ends;
        cin.ignore(numeric_limits<streamsize>::max(), '\n');
        getline(cin,fname);
        fname.append(".ett");
        int x;
        x = fname.length();
        char fname2[x];
        for(int b = 0; b <= x; b++){
            fname2[b] = fname[b];
        }
        ifstream inf(fname2);
        if(!inf){
            cout<<"\nERROR: The file \""<<fname2<<"\" could not be opened!\n";
            cout<<"Press any key to exit...\n";
            getche();
            exit(1);
        }
        passp = inf.get();
        if(passp == 1){
            getline(inf,passc);
            while(true){
                cout<<"\nPassword?\n::"<<ends;
                cin>>pass;
                passb = pass;
                for(x = 0;x <= passl;x++){
                    if(pass[x] != '\0'){
                        pass[x]= ((pass[x] + 5) * 2) - 3;
                    }
                }
                passl = pass.length();
                if(pass == passc){
                    cout<<"\nPassword correct"<<endl;
                    while(true){
                        getline(inf,fstxt);
                        x = fstxt.length();
                        int  y = passb.length();
                        y = y - 1;
                        x = x - 1;
                        int b = 0, c = 0, ud = 0;
                        for(b == 0,c == 0,ud == 0; b <= x; b++){
                            fstxt[b] = (fstxt[b] + passb[c]) - (passb[c]*2);
                            cout<<fstxt[b];
                            if(c == y){
                                ud = 1;
                            }
                            if(c == 0){
                                ud = 0;
                            }
                            for(;;){
                                if(ud == 0 && c < y){
                                    c = c + 1;
                                }
                                if(ud == 1 && c > 0){
                                    c = c - 1;
                                }
                                break;
                            }
                        }
                    break;
                    }
                cout<<endl<<"Press any key to exit..."<<endl;
                getche();
                break;
                }
                else{
                    cout<<"\nPassword incorrect"<<endl;
                }
            }
        }
        if(passp == 0){
            cout<<"\nFile is not password protected,\njust open it in a text editor like notepad..."<<endl;
            getche();
            exit(0);
        }
        else if(!(passp == 1 || 0)){
            cout<<"\nERROR: Something is wrong with the file..."<<endl;
            getche();
            exit(1);
        }
	}
}


EDIT: also, the math header I put in there I don't think is needed, I had put it in there during development cause I thought that my program wasn't doing what I wanted because it wasn't doing the math right or something, but I have been to lazy to actually look up what is in the header(function wise), but I figured I'd leave it in there just in case.
Last edited on
Topic archived. No new replies allowed.