C++ Vigenere and Caesar cipher in the same programming with switch case - c++

In the first code I did a Caesar cipher and it is working well. However, i cannot added Vigenere. There is a class and some pointers, but they do not work in the switch-case statement, so I need help.
encryption part is switch case :3
decryption part is switch case :4
#include <iostream>
#include <string.h>
#include <string>
using namespace std;
char message[200], ch;
int i, key;
string k,output,messageV;
int menu(int answer);
int main()
{
int answer;
bool keepLooping = true;
while (keepLooping)
{
cout << "Pick a Choice from the List: \n(1)Caesar \n(2)Vigenere \n ";
cin >> answer;
if (answer == 1)
{
while(keepLooping)
{
cout << "Pick a Choice from the List: \n(1)Encryption\n(2)Decryption \n ";
cin >> answer;
if (answer == 1)
{
answer = 1;
keepLooping = false ;
}
else if(answer == 2)
{
answer = 2;
keepLooping = false;
}
else
{
keepLooping = true;
}
}
}
else if(answer == 2)
{
while(keepLooping)
{
cout << "Pick a Choice from the List: \n(1)Encryption\n(2)Decryption \n ";
cin >> answer;
if (answer == 1)
{
answer = 3;
keepLooping = false ;
}
else if(answer == 2)
{
answer = 4;
keepLooping = false;
}
else
{
keepLooping = true;
}
}
}
else
{
keepLooping = true;
}
}
menu(answer);
}
int menu(int answer)
{
switch (answer)
{
case 1://Caesar Cipher Encryption
cout << "Enter a message to encrypt: ";
cin.ignore();
cin.getline(message, 200);
cout << "Enter key: ";
cin >> key;
for(i = 0; message[i] != '\0'; ++i){
ch = message[i];
if(ch >= 'a' && ch <= 'z'){
ch = ch + key;
if(ch > 'z'){
ch = ch - 'z' + 'a' - 1;
}
message[i] = ch;
}
else if(ch >= 'A' && ch <= 'Z'){
ch = ch + key;
if(ch > 'Z'){
ch = ch - 'Z' + 'A' - 1;
}
message[i] = ch;
}
}
cout << "Encrypted message: " << message;
break;
case 2://Caesar Cipher Decryption
cout << "Enter a message to decrypt: ";
cin.ignore();
cin.getline(message, 200);
cout << "Enter key: ";
cin >> key;
for(i = 0; message[i] != '\0'; ++i){
ch = message[i];
if(ch >= 'a' && ch <= 'z'){
ch = ch - key;
if(ch < 'a'){
ch = ch + 'z' - 'a' + 1;
}
message[i] = ch;
}
else if(ch >= 'A' && ch <= 'Z'){
ch = ch - key;
if(ch > 'a'){
ch = ch + 'Z' - 'A' + 1;
}
message[i] = ch;
}
}
cout << "Decrypted message: " << message;
break;
case 3:
cout << "CASE 3";
break;
case 4:
cout << "CASE 4";
break;
default:
cout << "There is no choices." << endl;
}
return answer;
}
Vigenere part:
#include <iostream>
#include <string>
using namespace std;
class Vig {
public:
string k;
Vig(string k) {
for (int i = 0; i < k.size(); ++i) {
if (k[i] >= 'A' && k[i] <= 'Z')
this->k += k[i];
else if (k[i] >= 'a' && k[i] <= 'z')
this->k += k[i] + 'A' - 'a';
}
}
string encryption(string t) {
string output;
for (int i = 0, j = 0; i < t.length(); ++i) {
char c = t[i];
if (c >= 'a' && c <= 'z')
c += 'A' - 'a';
else if (c < 'A' || c > 'Z')
continue;
output += (c + k[j] - 2 * 'A') % 26 + 'A'; //added 'A' to bring it in range of ASCII alphabet [ 65-90 | A-Z ]
j = (j + 1) % k.length();
}
return output;
}
string decryption(string t) {
string output;
for (int i = 0, j = 0; i < t.length(); ++i) {
char c = t[i];
if (c >= 'a' && c <= 'z')
c += 'A' - 'a';
else if (c < 'A' || c > 'Z')
continue;
output += (c - k[j] + 26) % 26 + 'A';//added 'A' to bring it in range of ASCII alphabet [ 65-90 | A-Z ]
j = (j + 1) % k.length();
}
return output;
}
};
int main() {
char message[200];
string key;
cout << "Key: ";
cin >> key;
cin.ignore();
Vig v(key);
cout << "Enter a message to encrypt: ";
cin.getline(message, 200);
string ori = message;
string encrypt = v.encryption(ori);
string decrypt = v.decryption(encrypt);
cout << "Original Message: "<<ori<< endl;
cout << "Encrypted Message: " << encrypt << endl;
cout << "Decrypted Message: " << decrypt << endl;
}

My suggestion is that you try to find the common patterns in your two programs. For example you have you have to methods to encrypt and decrypt. That could be abstracted into two different classes, perhaps with a common base-class defining the interface (allowing things like polymorphism):
struct Cipher
{
virtual std::string encryption(std::string const&) = 0;
virtual std::string decryption(std::string const&) = 0;
};
class Caesar : public Cipher
{
public:
std::string encryption(std::string const& s) override
{
// TODO: Implement Caesar cipher encryption
}
std::string decryption(std::string const& s) override
{
// TODO: Implement Caesar cipher decryption
}
};
class Vigenere : public Cipher
{
public:
std::string encryption(std::string const& s) override
{
// TODO: Implement Vigenere cipher encryption
}
std::string decryption(std::string const& s) override
{
// TODO: Implement Vigenere cipher decryption
}
};
From this we could create a set of functions to use any cipher (through pointers to the base Cipher class). Lets start with selecting which cipher to use:
Cipher* select_cipher()
{
std::cout << "Please select cipher to use:\n";
std::cout << "1) Caesar\n";
std::cout << "2) Vigenere\n";
int selection;
std::cin >> selection;
if (selection == 1)
{
return new Caesar;
}
else if (selection == 2)
{
return new Vigenere;
}
else
{
return nullptr;
}
}
Now we have a cipher to use, then select what to do:
int select_method()
{
std::cout << "Do you want to encrypt or decrypt?\n";
std::cout << "1) Encrypt\n";
std::cout << "2) Decrypt\n";
int method;
std::cin >> method;
return method;
}
Now we really have everything needed to use any supported cipher and method:
int main()
{
Cipher* cipher = select_cipher();
int method = select_method();
std::string input;
std::string result;
// TODO: Read input string to encrypt or decrypt
if (method == 1)
{
result = cipher->encryption(input);
}
else if (method == 2)
{
result = cipher->decryption(input);
}
std::cout << "Result = " << result << '\n';
}
Do note that this is only a very rough outline, and there are many parts missing (like the actual encryption and decryption algorithms). These are left as an exercise for the readers.
Instead of using if ... else if ... you can of course use switch. But for these simple cases it doesn't really matter, and if ... else if ... is, IMO, easier to read.

I coded it already can you check it too, please ?
#include <iostream>
#include <string>
using namespace std;
class Vig {
public:
string k;
Vig(string k) {
for (int i = 0; i < k.size(); ++i) {
if (k[i] >= 'A' && k[i] <= 'Z')
this->k += k[i];
else if (k[i] >= 'a' && k[i] <= 'z')
this->k += k[i] + 'A' - 'a';
}
}
string Vegencryption(string t) {
string output;
for (int i = 0, j = 0; i < t.length(); ++i) {
char c = t[i];
if (c >= 'a' && c <= 'z')
c += 'A' - 'a';
else if (c < 'A' || c > 'Z')
continue;
output += (c + k[j] - 2 * 'A') % 26 + 'A'; //added 'A' to bring it in range of ASCII alphabet [ 65-90 | A-Z ]
j = (j + 1) % k.length();
}
return output;
}
string Vegdecryption(string t) {
string output;
for (int i = 0, j = 0; i < t.length(); ++i) {
char c = t[i];
if (c >= 'a' && c <= 'z')
c += 'A' - 'a';
else if (c < 'A' || c > 'Z')
continue;
output += (c - k[j] + 26) % 26 + 'A';//added 'A' to bring it in range of ASCII alphabet [ 65-90 | A-Z ]
j = (j + 1) % k.length();
}
return output;
}
string Cesencryption(string t, int key){
string output;
char ch;
for(int i = 0; t[i] != '\0'; ++i){
ch = t[i];
if(ch >= 'a' && ch <= 'z'){
ch = ch + key;
if(ch > 'z'){
ch = ch - 'z' + 'a' - 1;
}
t[i] = ch;
}
else if(ch >= 'A' && ch <= 'Z'){
ch = ch + key;
if(ch > 'Z'){
ch = ch - 'Z' + 'A' - 1;
}
t[i] = ch;
}
}
output = t;
return output;
}
string Cesdencryption(string t, int key){
string output;
char ch;
for(int i = 0; t[i] != '\0'; ++i){
ch = t[i];
if(ch >= 'a' && ch <= 'z'){
ch = ch - key;
if(ch < 'a'){
ch = ch + 'z' - 'a' + 1;
}
t[i] = ch;
}
else if(ch >= 'A' && ch <= 'Z'){
ch = ch - key;
if(ch > 'a'){
ch = ch + 'Z' - 'A' + 1;
}
t[i] = ch;
}
}
output = t;
return output;
}
};
int main() {
char message[200];
string key;
int choice;
cout << "Pick a Choice from the List: \n(1)Caesar \n(2)Vigenere \n ";
cin >> choice;
if(choice == 2) //Vigenere
{
cout << "Pick a Choice from the List: \n(1)Encryption\n(2)Decryption \n ";
cin >> choice;
if (choice == 1)
{
cout << "Key: ";
cin >> key;
cin.ignore();
Vig v(key);
cout << "Enter a message to encrypt: ";
cin.getline(message, 200);
string ori = message;
string encrypt = v.Vegencryption(ori);
cout << "Encrypted Message: " << encrypt << endl;
}
else if (choice == 2)
{
cout << "Key: ";
cin >> key;
cin.ignore();
Vig v(key);
cout << "Enter a message to encrypt: ";
cin.getline(message, 200);
string ori = message;
string decrypt = v.Vegdecryption(ori);
cout << "Decrypted Message: " << decrypt << endl;
}
else
{
cout << "You Exit the Program.";
}
}
else if (choice == 1) //Ceaser
{
cout << "Pick a Choice from the List: \n(1)Encryption\n(2)Decryption \n ";
cin >> choice;
if (choice == 1)
{
int key;
cout << "Enter a message to encrypt: ";
cin.ignore();
cin.getline(message, 200);
cout << "Enter key: ";
cin >> key;
Vig v(message);
string ori = message;
string decrypt = v.Cesencryption(ori,key);
cout << "Decrypted Message: " << decrypt << endl;
}
else if (choice == 2)
{
int key;
cout << "Enter a message to dencrypt: ";
cin.ignore();
cin.getline(message, 200);
cout << "Enter key: ";
cin >> key;
Vig v(message);
string ori = message;
string encryption = v.Cesdencryption(ori,key);
cout << "Decrypted Message: " << encryption << endl;
}
else
{
cout << "You Exit the Program.";
}
}
else
{
cout << "You Exit the Program.";
}
}

Related

How can I simplify the For loop(c++)? [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 4 months ago.
Improve this question
I found a code on the internet to encrypt user input with Caesar encryption. But in the code the loop head bother me, because we didn't have things like "message[i]" or "\0" in class. Is it possible to write this in a different way? But we had not used arrays as far as in this loop header. This is not homework or anything like that. I'm practicing for my computer science test next week and there will probably be something similar. The loop header always looked like this for example for(i = 0; i < 4; i++). How can I write this code without arrays?
How can I write the loop differently? Or do I have to change other code parts?
#include <iostream>
using namespace std;
int main()
{
char message[100], ch;
int i, key;
cout << "Enter a message to encrypt: ";
cin.getline(message, 100);
cout << "Enter key: ";
cin >> key;
for (i = 0; message[i] != '\0'; ++i)
{ //<-
ch = message[i]; //<-
if (ch >= 'a' && ch <= 'z')
{
ch = ch + key;
if (ch > 'z')
{
ch = ch - 'z' + 'a' - 1;
}
message[i] = ch; //<-
}
else if (ch >= 'A' && ch <= 'Z')
{
ch = ch + key;
if (ch > 'Z')
{
ch = ch - 'Z' + 'A' - 1;
}
message[i] = ch; //<-
}
}
cout << "Encrypted message: " << message;
return 0;
}
To have a for loop closer to what you are used to, we need to know how many letters were input. The smallest change that does that is to use strlen to count them.
for (i = 0; i < strlen(message); ++i)
However it's better to use std::string to hold text, because that knows it's size.
int main()
{
std::string message;
int key;
std::cout << "Enter a message to encrypt: ";
std::getline(std::cin, message);
std::cout << "Enter key: ";
std::cin >> key;
for (i = 0; i < message.size(); ++i)
{
char ch = message[i];
if (ch >= 'a' && ch <= 'z')
{
ch = ch + key;
if (ch > 'z')
{
ch = ch - 'z' + 'a' - 1;
}
message[i] = ch; //<-
}
else if (ch >= 'A' && ch <= 'Z')
{
ch = ch + key;
if (ch > 'Z')
{
ch = ch - 'Z' + 'A' - 1;
}
message[i] = ch; //<-
}
}
std::cout << "Encrypted message: " << message;
return 0;
}
And even better than that, you can loop over the chars in a string directly
int main()
{
std::string message;
int key;
std::cout << "Enter a message to encrypt: ";
std::getline(std::cin, message);
std::cout << "Enter key: ";
std::cin >> key;
for (char & ch : message) // <- N.b. char &, we are modifying the `char` objects owned by message
{
if (ch >= 'a' && ch <= 'z')
{
ch = ch + key;
if (ch > 'z')
{
ch = ch - 'z' + 'a' - 1;
}
}
else if (ch >= 'A' && ch <= 'Z')
{
ch = ch + key;
if (ch > 'Z')
{
ch = ch - 'Z' + 'A' - 1;
}
}
}
std::cout << "Encrypted message: " << message;
return 0;
}
Look at this snippet. Sorry if I have made a mistake with syntax, but this is enough to give you a general idea.
#include <iostream>
#include <cctype>
using namespace std;
int main() {
char message[100];
int key;
cout << "Enter a message to encrypt: ";
cin.getline(message, 100);
cout << "Enter key: ";
cin >> key;
encrypt(message, key);
cout << "Encrypted message: " << message;
return 0;
}
void encrypt(char& message, const int key) {
for (char& ch : message) {
if (islower (ch))
ch = encrypt (ch + key, 'a', 'z');
else if (isupper (message[i]))
ch = encrypt (ch + key, 'A', 'Z');
}
}
char encrypt(const char ch, const char lo, const char hi) {
return ch % hi ? lo + (chi % hi) : ch;
}

How to use cache in c++?

I have a task to create an application for encoding and decoding using Atbash cipher. I have done the encoding/decoding thing but another part of the task is to cache the already encoded/decoded strings. Cache should be printable with standard stream operators and should be able to be stored and loaded in/from a file. Could someone help me to do it? Thanks in advance! This is my code by now:
#include <iostream>
#include <string>
using namespace std;
string Atbash_cipher(string message)
{
string upperAlpha = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
string reverseUpperAlpha = "ZYXWVUTSRQPONMLKJIHGFEDCBA";
string lowerAlpha = "abcdefghijklmnopqrstuvwxyz";
string reverseLowerAlpha = "zyxwvutsrqponmlkjihgfedcba";
string cipher = "";
for (int i = 0; i < message.length(); i++)
{
if (message[i] >= 32 && message[i] <= 64 && message[i] >= 173 && message[i] <= 176)
{
cipher += message[i];
}
if (message[i] >= 'A' && message[i] <= 'Z')
{
for (int j = 0; j < upperAlpha.length(); j++) {
if (message[i] == upperAlpha[j])
{
cipher += reverseUpperAlpha[j];
break;
}
}
}
else
{
for (int j = 0; j < lowerAlpha.length(); j++)
{
if (message[i] == lowerAlpha[j])
{
cipher += reverseLowerAlpha[j];
break;
}
}
}
}
return cipher;
}
void menu()
{
int choice;
string message;
do
{
cout << "1. Encrypt message" << endl << "2. Decrypt message" << endl << "0. Exit" <<
endl << "Your choice: ";
cin >> choice;
switch (choice)
{
case 1:
cout << "Enter message to encrypt: ";
cin.ignore();
getline(cin, message);
cout<< Atbash_cipher(message) <<endl;
break;
case 2:
cout << "Enter message to encrypt: ";
cin.ignore();
getline(cin, message);
cout << Atbash_cipher(message) << endl;
break;
}
} while (choice != 0);
}
int main()
{
menu();
return 0;
}

Error passing values into array/values in array missing

I have a text file and I passed it to a char array. It was fine when I display in a getline() loop but after going through encryption, only the last line is encrypted and displayed. I have tried to display values in array before entering shift key and what is inside the array is the last line of the text only. What has went wrong? Please help!!
char msg[5000];
string plaintext;
int choice, shift;
char ch;
// Read file into char array
ifstream infile("plaintext.txt");
while (getline(infile, plaintext))
{
strcpy_s(msg, plaintext.c_str());
for (int i = 0; i < plaintext.length(); i++)
{
cout << msg[i];
}
}
cout << endl;
cout << "Enter shift key: ";
cin >> shift; //take the shift as input
cout << "Enter your choice" << endl;
cout << "1.Encryption" << endl;
cout << "2.Decryption" << endl;
cin >> choice;
// Encryption
if (choice == 1)
{
for (int i = 0; msg[i] != '\0'; i++) {
ch = msg[i];
//encrypt for lowercase letter
if(ch >= 'a' && ch <= 'z') {
ch = ch + shift;
if (ch > 'z') {
ch = ch - 'z' + 'a' - 1;
}
msg[i] = ch;
}
//encrypt for uppercase letter
else if (ch >= 'A' && ch <= 'Z') {
ch = ch + shift;
if (ch > 'Z') {
ch = ch - 'Z' + 'A' - 1;
}
msg[i] = ch;
}
}
printf("Encrypted message: %s", msg);
}
result
This is wrong because you need to use strcat too
// Read file into char array
ifstream infile("plaintext.txt");
while (getline(infile, plaintext))
{
strcpy_s(msg, plaintext.c_str());
for (int i = 0; i < plaintext.length(); i++)
{
cout << msg[i];
}
}
Instead:
// Read file into char array
ifstream infile("plaintext.txt");
getline(infile, plaintext)
if (!plaintext.empty())
{
strcpy_s(msg, plaintext.c_str());
plaintext.clear();
while (getline(infile, plaintext))
{
strcat_s(msg, sizeof msg, plaintext.c_str());
for (int i = 0; i < plaintext.length(); i++)
{
cout << msg[i];
}
plaintext.clear();
}
}

Extracting a vowels from an array..and storing nd printing on another array

Write a program using for loop which stores alphabets from Z-A. Extract only vowels from this array and store them into another array vowels. Now display these vowels using for loop from vowels array.
My output is not working properly. If I write my name without spaces like abdulhananhamid, then it works and shows a u a a.
I do not know how to use cin in a for loop, either.
#include<iostream>
#include<conio.h>
using namespace std;
int vowel (char x);
int main()
{
char size=100;
char x[size];
char A[5];
int n,i,;
cout<<"Enter any string\n";
cin>>x;
for (i = 0, n = 0; i<size; i++)
if (vowel(x[i]))
A[n++] = x[i];
for (n = 0;n<5;n++)
cout << A[n] << " ";
getch();
return 0;
}
int vowel(char x)
{
if(x=='a'||x=='e'||x=='i'||x=='o'||x=='u')
return 1;
else
return 0;
}
This looks like a good assignment for using std::string and std::getline.
std::string user_text;
std::cout << "Enter a string: ";
while (std::getline(std::cin, user_text)
{
const size_t length = user_text.length();
std::string vowels;
for (size_t i = 0; i < length; ++i)
{
const char c = user_text[i];
if ((c == 'a') || (c == 'e') || (c == 'i') || (c == 'o') || (c == 'u'))
{
vowels += c;
}
}
std::cout << "Vowels found: " << vowels << "\n";
std::cout << "\nEnter a string: ";
}
If you must use character arrays, you should check for overflow:
unsigned int MAXIMUM_CHARACTERS = 128;
char user_text[MAXIMUM_CHARACTERS];
char vowels_found[MAXIMUM_CHARACTERS];
std::cout << "Enter a string: ";
while (std::cin.getline(&user_text[0], MAXIMUM_CHARACTERS))
{
unsigned int vowel_index = 0U;
const size_t length = strlen(user_text);
for (size_t i = 0; i < length; ++i)
{
const char c = user_text[i];
if ((c == 'a') || (c == 'e') || (c == 'i') || (c == 'o') || (c == 'u'))
{
vowels_found[vowel_index++] = c;
}
}
vowels_found[vowel_index] = '\0';
std::cout << "Vowels found: " << vowels_found << "\n";
std::cout << "\nEnter a string: ";
}
A function for checking for a vowel could look like:
bool is_vowel(char c)
{
return (c == 'a') || (c == 'e') || (c == 'i') || (c == 'o') || (c == 'u');
}

program skip over getline

I am suppose to create a program such that when 'y' is entered it will execute the code in the first do-while loop. however, when 'y' is entered it just skips over the chunk of codes!
Enter a phone symbols:
a
2
Continue (Y/y): y
Enter a phone symbols:
Continue (Y/y):
Is there anyway I can solve this without using cin.ignore as it changes the layout. Thanks in advance!
#include <iostream>
#include <cstdlib>
#include <cctype>
#include <iomanip>
#include <cstring>
const int MAX = 100;
using namespace std;
int getInt(char);
bool isValidChar(char);
int main()
{
int num;
int j = 0;
char name, conti;
char alpha[MAX];
do {
cout << "Enter a phone symbols: " << endl;
cin.getline(alpha, MAX);
// cin.ignore(100, '\n');
while (alpha[j] != '\0')
{
name = alpha[j];
if (isValidChar(name) == true)
{
num = getInt(name);
if (num == -1)
{
cout << "-";
}
else
{
cout << num;
}
}
else
{
cout << " - Invalid Char " << name << " found - rejected";
}
j++;
} // end while
cout << endl;
do {
cout << "\nContinue (Y/y): ";
cin >> conti;
cout << "\n" << endl;
conti = tolower(conti);
if (conti == 'n')
{
exit(0);
}
} while (conti != 'n' && conti != 'y');
} while (conti == 'y');
}
int getInt(char input)
{
int result;
char value;
value = tolower(input);
if ((value >= 'a' && value <= 'c'))
{
result = 2;
}
else if ((value >= 'd' && value <= 'f'))
{
result = 3;
}
else if ((value >= 'g' && value <= 'i'))
{
result = 4;
}
else if ((value >= 'j' && value <= 'l'))
{
result = 5;
}
else if ((value >= 'm' && value <= 'o'))
{
result = 6;
}
else if ((value >= 'p' && value <= 's'))
{
result = 7;
}
else if ((value >= 't' && value <= 'v'))
{
result = 8;
}
else if ((value >= 'w' && value <= 'z'))
{
result = 9;
}
else if (value == ' ')
{
result = -1;
}
return result;
}
bool isValidChar(char value)
{
if (isalpha(value) || value == ' ')
{
return true;
}
else
{
return false;
}
}
What do you mean as: Is there anyway I can solve this without using cin.ignore as it changes the layout.?
Your layout is contolled, basicly by this line:
cout << "\nContinue (Y/y): ";
cin >> conti;
cout << "\n" << endl; // <-- this one
conti = tolower(conti);
If you supress it, there will be no empty line. Otherwise, if you change it to
cout << endl;
Just one empty line.