Encryption and decryption with ASCII in C++ [closed] - c++

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 6 years ago.
Improve this question
As I am new to coding c++ and am taking a object oriented class, I need some help. For this code I want to encrypt it by shifting all of the text that is enter by 1 ascii digit i.e. a -> b, b-> etc. I am suppose to use all ascii values 32 - 126 but I cant figure out why when i try to encrypt anything I only get a "^" as a output.
#include <iostream>
#include <string>
using namespace std;
void encrypt (string &encrypt)
{
string encryption;
for (int i = 0; i < encrypt.length(); i++)
{
encrypt[i]++;
if (i > 126){
encrypt = i - 94;
}
else if (i < 32){
encrypt = i + 94;
}
}
}
void decrypt (string decrypt)
{
string decryption;
for ( int i = 0; i < decryption.length(); i ++)
{
decryption[i]--;
if (i > 126){
decrypt = i + 94;
}
else if (i < 32){
decrypt = i - 94;
}
}
}
int main ()
{
string option;
string encryption1;
string decryption1;
cout << "Do you want to encrypt or decrypt? \n";
cin >> option;
if (option == "encrypt")
{
cout << "What do you want to encrypt \n";
cin.ignore();
cin.clear();
getline (cin, encryption1);
encrypt ( encryption1);
cout << encryption1 << " " << endl;
}
if (option == "decrypt")
{
cout << "What do you want to decrypt \n";
cin.ignore();
cin.clear();
getline (cin, decryption1);
encrypt ( decryption1);
cout << decryption1 << " " << endl;
}
return 0;**

I did something similar to this in my level one programming class last year. We created a Vigenere Cipher that is based off of the architecture of the Cesar cipher.
Something that is useful is to first create a 0 base, i.e. if you are working with values a through b, subtract a from each of the characters that you are encoding first, do the math, double check that the value falls within the range of values (32 through 126 == 0 through 94) and then return the char + a. This would mean rewriting your logic and function to take a char instead of the entire string at once.
As for why you are getting '^' as your only output, the ACSII code for '^' is 94 and your code:
for ( int i = 0; i < decryption.length(); i ++)
{
decryption[i]--;
if (i > 126){
decrypt = i + 94;
}
else if (i < 32){
decrypt = i - 94;
}
}
}
is setting the entire string to char 94. You set i = 0 then say that if i is less than 32 then the string decrypt is equal to the char 0 + 94 which is equal to 94 which is equal to '^'

Related

Searching for the frequency of a word in a string (C++) [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 2 years ago.
Improve this question
I have to write a program that asks the user for a sentence (with a limit of 1024 letters), then asks the user for a word, and tells the user how many times that specific word occurs in the sentence, for an assignment.
We're only allowed to use these libraries: iostream, string, cstring, cstdlib, cmath and fstream.
example of how it's supposed to function:
Enter a sentence:
input:hello my name is hello hello
Enter a word to check for frequency:
input:hello
desired output:# of times word occurs: 3
actual output:# of times word occurs: 25
This is what I tried using with the help of a friend, but when I enter a word to search it outputs an unrelated number.
int wordFrequency(){
char sen5[1024];
int frequency = 0;
char word[1024];
cout << "Enter a sentence: " << endl;
cin.getline(sen5, 1024);
cout << "Enter a word to check for frequency: " << endl;
cin.getline(word, 1024);
for(int i = 0; i < strlen(sen5); i++){
if(sen5[i] == word[i]){
for(int j = 0; j < strlen(word); j++)
if(sen5[j] == word[j])
frequency += 1;
}
}
cout << "# of times word occurs: " << frequency << endl;
return 0;
}
Also, I'm aware my coding is horrid, my professor is notoriously horrible and I'm struggling immensely in my class because of it. Any help is appreciated.
So friend if you are only allowed to use isostream,, string, cstring, cstdlib, cmath and fstream. then you can program it in C++ language.
So below code only uses iostream for input/output operations.
you can also use string.h to find the string length but i have gone the other way.
for finding the occurrence's of a word below is the function:
int countOccurrences(char * str, char * toSearch)
{
int i, j, found, count;
int stringLen, searchLen;
int cou = 0;
while(str[cou] != '\0'){
cou++;
}
stringLen = cou;
cou = 0;
while(toSearch[cou] != '\0'){
cou++;
}
searchLen = cou;
count = 0;
for(i=0; i <= stringLen-searchLen; i++)
{
found = 1;
for(j=0; j<searchLen; j++)
{
if(str[i + j] != toSearch[j])
{
found = 0;
break;
}
}
if(found == 1)
{
count++;
}
}
return count;
}
And for taking the input you can write the things in main function and then call the above function in main. Below is the code for that:
int main()
{
char str[MAX_SIZE];
char toSearch[MAX_SIZE];
int count;
cout<<"Enter any string: "<<endl;
cin.getline(str, sizeof(str));
cout<<"Enter word to search occurrences: "<<endl;
cin.getline(toSearch, sizeof(toSearch));
count = countOccurrences(str, toSearch);
cout<<"Total occurrences of"<< toSearch<<" : "<< count;
return 0;
}
It seems you are beginner in the coding stuff so for more:
below is the code you need to add at the starting of your code. Header file and declaring the countOccurences function.
#include <iostream>
#define MAX_SIZE 100
using namespace std;
int countOccurrences(char * str, char * toSearch);
So this way you can count the number of occurrences/frequency of a word in a string with using iostream header only.

Need assistance with Vigenere Cipher program

I am helping a friend create a program that encrypts/decrypts messages using the "Vigenere Cipher." I was unsure what this was, so I did my own research and think I have it figured out.
My code runs fine from a syntax perspective. But, from a logic perspective, it does not work. From my understanding, when I encrypt a message with a key, if I decrypt the encrypted message using the same key, it should give me the original message. Mine does not. From my debugging attempts, I think the issue lies somewhere in my decrypting algorithm, but could be entirely wrong.
Here is my code:
#include <iostream>
#include<stdio.h>
#include<string.h>
#include<iostream>
#include<string>
using namespace std;
int main(){
//initializing functions to be used
int giveInfo();
void encrypt(string message, string key);
void decrypt(string message, string key);
void newKey(string key);
string keyInput();
string messageInput();
int userChoice();
giveInfo();
//loop so that the user can decrypt/encrypt multiple messages
int counter = 1;
int userCounter;
while (counter == 1){
int choice = userChoice();
if(choice == 1){
string inputMessage = messageInput();
string inputKey = keyInput();
encrypt(inputMessage, inputKey);
}
else{
string inputMessage = messageInput();
string inputKey = keyInput();
decrypt(inputMessage, inputKey);
}
cout << "Would you like to decrypt/encrypt another message? (1 = yes, 2 = no)";
cin >> userCounter;
counter = userCounter;
system("CLS");
}
return 0;
}
//gives the user a basic description of cypher and what they need to input
int giveInfo(){
cout << "\nThe Vigenere Cypher is a polyalphabetic encryption/decryption method. It utilizes a 'key' (provided by the user, \nany word of any length) to determine which letters will replace others. This means in order to decrypt a message,\n one will need the key the person who encrypted the messafe used, ensuring a secure encryption. To use this program, \nyou will need to enter your message (this will be converted into all capitol letters) and a key which you would like to use. Do not use any spaces in your message.\n\n\n";
return 0;
}
string messageInput(){
//message place holder
string userMessage;
//asking for message
cout << "What is the message you would like to encrypt/decrypt?\n";
cin >> userMessage;
return userMessage;
}
string keyInput(){
//key place holder
string userKey;
//asking for key
cout << "What is the key you would like to use?\n";
cin >> userKey;
return userKey;
}
void decrypt(string message, string key){
//generating new key to match message length
int x = message.size();
for (int i = 0; ; i++)
{
if (x == i)
i = 0;
if (key.size() == message.size())
break;
key.push_back(key[i]);
}
string orig_text;
for (int i = 0 ; i < message.size(); i++)
{
// converting in range 0-25
int x = (message[i] - key[i] + 26) %26;
// convert into alphabets(ASCII)
x += 'A';
orig_text.push_back(x);
}
cout << "\n\nEncrypted Code: " + message+ "\n";
cout << "Key: " + key+ "\n";
cout << "Decrypted message: ";
cout << orig_text + "\n";
}
//takes user input (message to be encyrpted and key to be used) as arguments and returns encrypted
void encrypt(string message, string key){
string cipher_text;
//generating new key to match message length
int x = message.size();
for (int i = 0; ; i++)
{
if (x == i)
i = 0;
if (key.size() == message.size())
break;
key.push_back(key[i]);
}
for (int i = 0; i < message.size(); i++)
{
// converting in range 0-25
int x = (message[i] + key[i]) %26;
// convert into alphabets(ASCII)
x += 'A';
cipher_text.push_back(x);
}
cout << "\n\nOriginal message: " + message+ "\n";
cout << "Key: " + key+ "\n";
cout << "Encrypted message: ";
cout << cipher_text + "\n";
}
int userChoice(){
int choice;
cout << "Would you like to encrypt a message or decrypt a message? (1 =
encrypt, 2 = decrypt)\n";
cin >> choice;
return choice;
}
Any help?
Since your intention is to use an alphabet with a length of 26, you need to make sure your input is properly normalized prior to performing any encryption/decryption operations.
I would suggest ensuring that user input for the message & key is converted to upper case.
e.g. utilizing toupper: for(char &c : inputMessage) c = toupper(c)
Could you provide your input & output? Your code works just fine.
Original Message: ATTACKATDAWN
Key: LEMONLEMONLE
Encrypted Message: LXFOPVEFRNHR
Encrypted Code: LXFOPVEFRNHR
Key: LEMONLEMONLE
Decrypted Message: ATTACKATDAWN

Element counting issue [closed]

Closed. This question is not reproducible or was caused by typos. It is not currently accepting answers.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Closed 6 years ago.
Improve this question
#include <iostream>
using namespace std;
int countLetters(char text[], char letter);
int main()
{
char letter;
cout << "Enter a letter: ";
cin >> letter;
cin.ignore();
char text[1024];
cout << "Enter text: ";
cin.getline(text, 1024);
int letterCount = countLetters(text, letter);
cout << "Number of '" << letter << "'s: " << letterCount << endl;
return 0;
}
int countLetters(char text[], char letter)
{
int letterCount = 0;
for (int i = 0; i <= text[i]; i++)
{
if (letter == text[i])
letterCount++;
}
return letterCount;
}
This code, as written, is designed to ask the user for, first, the letter they want to search for in a line of text. Second, it will ask the user to input the line of text they want to have searched. Finally, it will spit out how many letters there are in the specific line of text they input.
My specific error lies here: when user asks for 'e' in "CS 124 - Introduction to Software Development", program only declares that there is one 'e' . I'm unsure what's wrong, because when you run the program and input 'o' while asking to search the exact same line of text, you get the proper number of 'o' values returned, 4.
Any ideas as to what my error is and why it glitches when searching for 'e' ?
Your for condition is wrong, the for loop should continue while i is less than text's length not the value of text[i]. Since this is C++ you should use strings not character arrays, why make it harder on yourself?
The code below is a C++ approach, note that my C++ is a bit rusty and the code might contain errors.
#include <iostream>
#include <string>
using namespace std;
int countLetters(string text, char letter);
int main() {
char letter = ' ';
string text;
cout << "Enter a letter: ";
cin >> letter;
cin.ignore();
cout << "Enter text: ";
getline(cin, text); // use 'getline(cin, text)' instead of 'cin >> text'
int letterCount = countLetters(text, letter);
cout << "Number of '" << letter << "'s: " << letterCount << endl;
return 0;
}
int countLetters(string text, char letter) {
int letterCount = 0;
for (int i = 0; i < text.size(); i++) {
if (letter == text[i]) {
letterCount += 1;
}
}
return letterCount;
}
change the condction
i <= text[i]
to
text[i] != '\0'

Preventing user from inputting certain chars in c++ [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 8 years ago.
Improve this question
I'm quite new to c++ so please understand that my question may be silly.
I need to create a function which takes from the user a table and fills it with only specific characters. Let's say that the user needs to input his name. If the user inputs a charater from A to Z (or a to z) the character should be displayed on the screen and in that case- everything is fine. The problem is- when the user inputs a forbidden character (for instance 1-9) this shouldn't be displayed on the screen and the cursor should stay in the same position).
Do you guys know how to do this?
May be you can use this to do your job:
char ch;
while(ch = getch())
{
if((ch>='A' && ch<='Z') || (ch>='a' && ch<='z'))
{
cout << ch;
}
}
This will print only [A-Z][a-z]. You can also store your required char to use further.
On Windows you can use conio.h.
Also, you can overload the istream::operator>> function to make solution more elegant and easy to use:
Complete example:
#include <iostream>
#include <conio.h>
using namespace std;
struct person_t
{
string name;
string last_name;
};
// This is the function you're looking for.
void get_filtered_string(string &str)
{
char c;
str = "";
do
{
c = _getch();
if (('A' <= c && c <= 'Z') || ('a' <= c && c <= 'z'))
{
putchar(c); // 1
str.push_back(c);
}
} while (c != '\r'); // 2
}
istream &operator>>(istream &stream, person_t &person)
{
string str = "";
cout << "Enter name: ";
get_filtered_string(str);
person.name = str;
cout << endl;
cout << "Enter last name: ";
get_filtered_string(str);
person.last_name = str;
cout << endl;
return stream;
}
int main()
{
person_t person;
cin >> person;
cout << person.name.c_str() << " " << person.last_name.c_str() << endl;
return 0;
}
Output character to screen.
In Windows when you hit Enter you're introducing two characters '\r' and '\n' in that order. Thats why we check here for '\r'.

Caesar cipher input text file

I am trying to create a Caesar cipher using C++. I have the program read in a text file but I need it to encrypt the text and output to the screen.
This is my encryption code but I can't seem to get it to work. I have only just started using C++ and not really sure where to go from here.
cout << "enter a value between 1-26 to encrypt the text: ";
cin >> shift;
while ((shift <1) || (shift >26)) {
cout << "Enter a value between 1 and 26!: ";
cin >> shift;
}
int size = strlen(text);
int i=0;
for(i=0; i<size; i++) {
cipher[i] = (text[i]);
if (islower(text[i])) {
if (text[i] > 122) {
cipher[i] = ( (int)(text[i] - 26) + shift);
}
} else if (isupper(text[i])) {
if (text[i] > 90) {
cipher[i] = ( (int)(text[i] - 26) + shift);
}
}
}
cipher[size] = '\0';
cout << cipher << endl;
First of all, your algorithm is wrong.
If we assume ASCII input then you need to encrypt the values that are between 32 (i.e. space) and 126 (i.e. tilde ~), inclusive. You do this by adding the key (a single number) to the value. If the result is greater than 126 (your highest available character) you need to wrap around and start counting from 32. This means 126 + 1 = 32, 126 + 2 = 33, etc. Look up "modulo".
I recommend you look-up the word "debugging". Generally, when you have an algorithm you write code that matches the algorithm as best you can. If the results are not the expected ones then you step line by line using the debugger until you find the line were your expected results and your code's result no longer match.
reformatted, made compilable ad fixed algorithm (to what i think was tried to achieve)
#include <iostream>
using namespace std;
char text[] = {"This is my encryption code but I can't seem to get it to work. "
"I have only just started using C++ and not really sure where "
"to go from here."};
char cipher[sizeof(text)];
void main()
{
int shift;
do {
cout << "enter a value between 1-26 to encrypt the text: ";
cin >> shift;
} while ((shift <1) || (shift >26));
int size = strlen(text);
int i=0;
for(i=0; i<size; i++)
{
cipher[i] = text[i];
if (islower(cipher[i])) {
cipher[i] = (cipher[i]-'a'+shift)%26+'a';
}
else if (isupper(cipher[i])) {
cipher[i] = (cipher[i]-'A'+shift)%26+'A';
}
}
cipher[size] = '\0';
cout << cipher << endl;
}
A few things:
You are checking if the character islower and then checking if the
ascii value is > 122. This will never be true. In the default
locale (standard ascii), islower() will only be true if the ascii
value is in the range [97, 122] (a-z). The same goes for
isupper(). It only returns true for ascii values between 65 and
90, inclusive.
You are already working with ascii values anyway, so islower() and isupper() may be redundant. Those are equivalent to doing bounds checking on the ranges, i.e. text[i] >= 97 && text[i] <= 122. They are useful shortcuts, but don't base your code around them if you can simplify.
Your code never adds the caesar shift if the value is <= 90/122, so you will never shift anything.