Decoding a previously encoded message

  • Thread starter Demon117
  • Start date
In summary: Code to encode the text cout<<"Encoding...\n"; file.write(crypt::encode()); //Writes the code to encode the text //Code to decode the text cout<<"Decoding...\n"; file.close(); //Closes file } cout<<"Thank you for choosing Magic Decoder Ring!\n";
  • #1
Demon117
165
1
I am making a encoder/decoder program. I have made most of it but I am stuck on the last bit. I would like when i click decode the text it will read encode.txt from the same directory, read it and change it back to normal (undecode) and then show it on the screen.

Please can someone help?


Here is my code:

Code:
#include <iostream>
#include <string>
#include <stdlib.h>
#include <fstream>
using namespace std;

const string cryptSymbols[]={"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","A","B","C",
"D","E","F","G","H","I","J","K","L","-"};

const string normalSymbols[]={"A","B","C","D","E","F","G","H","I","J","K","L","M",
"N","O","P","Q","R","S","T","U","V","W","X","Y","Z","1","2","3","4","5","6","7","8",
"9","0",".",","," "};

class crypt{
      string inCode;
public:
       crypt(string input);
       string decode();
       string encode();
};

crypt::crypt(string input){
                    inCode = input;
}

string crypt::decode(){
       
       string output="";
       string cryptLetter="";
       char character;
       char right;
       int pointer=0;
       
       while(pointer<inCode.length())
       {character=inCode[pointer];
       
       if(pointer<inCode.length()-1)
           right=inCode[pointer+1];
       if(!(character=' '))
           cryptLetter+=character;
       
       else{
            for(int ctr=0;ctr<39;ctr++){
                    if(cryptLetter==cryptSymbols[ctr])
                        output+=normalSymbols[ctr];
            }
            cryptLetter="";
       }
       if((character==' ')&&(right==' ')){
                        output+=" ";
       }
       pointer++;
       }
return output;
}  

string crypt::encode(){
       string output="";
       string character="";
       for(int ctr=0;ctr<inCode.length();ctr++){
               character=inCode[ctr];
               if(character==" ")
                    output+=" ";
               for(int ctr2=0;ctr2<38;ctr2++){
                       if(character==normalSymbols[ctr2]){
                             output+=cryptSymbols[ctr2];
                             output+=" ";
                       }
               }
       }
       
       return output;
       
}

int main()
{
    string input;
    string output;
    char choice;
    char yn;
    char number;
    yn='y';
    while((yn!='n')&&(yn!='N')){
        cout<<"Welcome to the Magic Decoder Ring!\n";
        cout<<"Please choose an option:\n";
        cout<<"1 Encode Text\n";
        cout<<"2 Decode Text\n";
        
        cin>>choice;
        cin.clear();
        cin.ignore();
        
        if(choice=='1'){
           ofstream file; //Declares file
           file.open("encode.txt"); //Opens file
           cout<<"Type the text you want encoded\n";
           getline(cin,input);
           crypt cryptCode(input+" ");
           output=cryptCode.decode();
           cout<<output<<'\n';
           file<<cryptCode.encode()<<endl;
           file.close();//Closes the file
           cout<<"(Your code has been saved at encode.txt)\n";
                 cin.clear();
        cin.ignore();
        }
        else if(choice=='2'){
             ifstream infile("encode.txt");
             crypt cryptCode(input+" ");
             output=cryptCode.decode();
                   getline(cin,input);
             cout<<output<<'\n';
        cout<<"-Finished...";
        cin.clear();
        cin.ignore();
        }
        
    system("pause");
    return EXIT_SUCCESS;
}}
 
Technology news on Phys.org
  • #2
matumich26 said:
I am making a encoder/decoder program. I have made most of it but I am stuck on the last bit. I would like when i click decode the text it will read encode.txt from the same directory, read it and change it back to normal (undecode) and then show it on the screen.

Please can someone help?
Does the code you show compile without errors? What exactly do you need help with?

I see at least one line where you are using = when you should be using ==
if(!(character=' ')) (in decode())

matumich26 said:
Here is my code:

Code:
#include <iostream>
#include <string>
#include <stdlib.h>
#include <fstream>
using namespace std;

const string cryptSymbols[]={"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","A","B","C",
"D","E","F","G","H","I","J","K","L","-"};

const string normalSymbols[]={"A","B","C","D","E","F","G","H","I","J","K","L","M",
"N","O","P","Q","R","S","T","U","V","W","X","Y","Z","1","2","3","4","5","6","7","8",
"9","0",".",","," "};

class crypt{
      string inCode;
public:
       crypt(string input);
       string decode();
       string encode();
};

crypt::crypt(string input){
                    inCode = input;
}

string crypt::decode(){
       
       string output="";
       string cryptLetter="";
       char character;
       char right;
       int pointer=0;
       
       while(pointer<inCode.length())
       {character=inCode[pointer];
       
       if(pointer<inCode.length()-1)
           right=inCode[pointer+1];
       if(!(character=' '))
           cryptLetter+=character;
       
       else{
            for(int ctr=0;ctr<39;ctr++){
                    if(cryptLetter==cryptSymbols[ctr])
                        output+=normalSymbols[ctr];
            }
            cryptLetter="";
       }
       if((character==' ')&&(right==' ')){
                        output+=" ";
       }
       pointer++;
       }
return output;
}  

string crypt::encode(){
       string output="";
       string character="";
       for(int ctr=0;ctr<inCode.length();ctr++){
               character=inCode[ctr];
               if(character==" ")
                    output+=" ";
               for(int ctr2=0;ctr2<38;ctr2++){
                       if(character==normalSymbols[ctr2]){
                             output+=cryptSymbols[ctr2];
                             output+=" ";
                       }
               }
       }
       
       return output;
       
}

int main()
{
    string input;
    string output;
    char choice;
    char yn;
    char number;
    yn='y';
    while((yn!='n')&&(yn!='N')){
        cout<<"Welcome to the Magic Decoder Ring!\n";
        cout<<"Please choose an option:\n";
        cout<<"1 Encode Text\n";
        cout<<"2 Decode Text\n";
        
        cin>>choice;
        cin.clear();
        cin.ignore();
        
        if(choice=='1'){
           ofstream file; //Declares file
           file.open("encode.txt"); //Opens file
           cout<<"Type the text you want encoded\n";
           getline(cin,input);
           crypt cryptCode(input+" ");
           output=cryptCode.decode();
           cout<<output<<'\n';
           file<<cryptCode.encode()<<endl;
           file.close();//Closes the file
           cout<<"(Your code has been saved at encode.txt)\n";
                 cin.clear();
        cin.ignore();
        }
        else if(choice=='2'){
             ifstream infile("encode.txt");
             crypt cryptCode(input+" ");
             output=cryptCode.decode();
                   getline(cin,input);
             cout<<output<<'\n';
        cout<<"-Finished...";
        cin.clear();
        cin.ignore();
        }
        
    system("pause");
    return EXIT_SUCCESS;
}}
 
  • #3
There are so many problems in there, it's a ways yet from working, alas.

Firstly, your indentation is truly terrible, I'm sorry to say. I suggest setting up an IDE to indent things automatically for you, at this point.

Doesn't compile for me because I believe there's a function called crypt in the std namespace. Renaming the class to Crypt (with upper case at the start) gets rid of that problem, but it should be named something more specific, or be in it's own namespace (won't get into that now). I prefer the convention where class names start with an upper case letter, personally.

EDIT: Not sure where the crypt function is coming from, to be honest, and you might not have it on your system. However, you should #include <cstdlib> and not #include <stdlib.h>. Also still a bad class name. Capitalizing the first letter of a class name prevents such problems, for the most part.

If you're appending repeatedly to a string, you might consider stringbuffer for it. That's what it's for.

In decode, you call an index "pointer". It's not a pointer. Might want to call it "index" or something like that.

The 'inCode' member variable should be private. Though one might question if it should be there at all rather than just passing the data to the encode/decode methods directly, is something to consider.

You're also not reading in the ciphertext from the input file, and so there's nothing for it to decode.

Mark already pointed out the line with '=' when you meant '=='.

Not sure what compiler you're using, but you should make sure warnings are on. One thing it should point out is that you're comparing an int and the return value of string::length(), when that method doesn't return an int. It returns size_t.

Why is there 'cin.ignore()' in those two places in main? Doesn't seem necessary.

That's what I see after a quick pass through. Not too sure about the logic in decode, either. But fix that stuff and see what happens, and we can give you more help if necessary.
 
Last edited:
  • #4
Firstly, your indentation is truly terrible, I'm sorry to say. I suggest setting up an IDE to indent things automatically for you, at this point.

Frankly I understand the indentation so I'll just ignore that comment.

Doesn't compile for me because I believe there's a function called crypt in the std namespace. Renaming the class to Crypt (with upper case at the start) gets rid of that problem, but it should be named something more specific, or be in it's own namespace (won't get into that now). I prefer the convention where class names start with an upper case letter, personally.

It compiles just fine for me, but it does encode rather funny like.
This is just confusing but here is what I gather:

Code:
class Crypt{
      string inCode;
public:
       Crypt(string input);
       string decode();
       string encode();
};

If you're appending repeatedly to a string, you might consider stringbuffer for it. That's what it's for.

I don't know what a sringbuffer is so I would prefer just leaving it.

In decode, you call an index "pointer". It's not a pointer. Might want to call it "index" or something like that.

I will fix that.

The 'inCode' member variable should be private. Though one might question if it should be there at all rather than just passing the data to the encode/decode methods directly, is something to consider.

How do I fix that? I would like to simplify this a bit..

You're also not reading in the ciphertext from the input file, and so there's nothing for it to decode.

Hmm, have to play with that for a bit. I am assuming that it would be kinda similar to what I have in main for encode().

Not sure what compiler you're using, but you should make sure warnings are on. One thing it should point out is that you're comparing an int and the return value of string::length(), when that method doesn't return an int. It returns size_t.

I'm assuming that's why I get silly encoded messages. For example, when I put in
"My name is charlie." The encoded file becomes "13 k " which does not seem right at all. . . .
 
  • #5
matumich26 said:
Frankly I understand the indentation so I'll just ignore that comment.
Don't you think it's an important courtesy to us to make it readable? It's, in fact, quite important to indent and format things well, for a number of reasons.

You're even indenting with a different number of spaces in different places.

I mean when is this ever acceptable:

Code:
       while(pointer<inCode.length())
       {character=inCode[pointer];

or later in the method:

Code:
       if((character==' ')&&(right==' ')){
                        output+=" ";
       }
       pointer++;
       }

There's a lot of room for formatting it how you like it. You don't have to indent it exactly the way I do, but this is how I would indent and format it (ignoring actual problems in the code except the =/== thing):

Code:
string crypt::decode() {
    string output = "";
    string cryptLetter = "";
    char character;
    char right;
    int pointer = 0;
       
    while (pointer < inCode.length()) {
        character = inCode[pointer];

        if (pointer < (inCode.length()-1))
            right = inCode[pointer+1];

        if (!(character == ' ')) {
            cryptLetter += character;
        } else {
            for (int ctr=0; ctr < 39; ctr++) {
                if (cryptLetter == cryptSymbols[ctr])
                    output += normalSymbols[ctr];
            }
            cryptLetter = "";
        }
        if ((character == ' ') && (right == ' ')) {
            output += " ";
        }
        pointer++;
    }
    return output;
}

I tend to prefer curly braces on their own lines, but that's a matter of choice and putting them at the end of the line is absolutely fine, but there should be a space before that opening curly brace. There's spaces added in many places that really improve clarity and readability.

There isn't a competent programmer on the planet that wouldn't rather work on the code as I indented it, nor a single one that would think your indentation is acceptable. If I was a teacher marking that, you'd lose points.

You're making extra work for us when we help you because we need to either put in extra effort to figure out the code structure, or re-indent it so it's readable. You can see where we'd be less inclined to want to help you in those circumstances. Help us help you.
 
  • #6
Grep said:
Don't you think it's an important courtesy to us to make it readable? It's, in fact, quite important to indent and format things well, for a number of reasons.

You're even indenting with a different number of spaces in different places.

I mean when is this ever acceptable:

Code:
       while(pointer<inCode.length())
       {character=inCode[pointer];

or later in the method:

Code:
       if((character==' ')&&(right==' ')){
                        output+=" ";
       }
       pointer++;
       }

There's a lot of room for formatting it how you like it. You don't have to indent it exactly the way I do, but this is how I would indent and format it (ignoring actual problems in the code except the =/== thing):

Code:
string crypt::decode() {
    string output = "";
    string cryptLetter = "";
    char character;
    char right;
    int pointer = 0;
       
    while (pointer < inCode.length()) {
        character = inCode[pointer];

        if (pointer < (inCode.length()-1))
            right = inCode[pointer+1];

        if (!(character == ' ')) {
            cryptLetter += character;
        } else {
            for (int ctr=0; ctr < 39; ctr++) {
                if (cryptLetter == cryptSymbols[ctr])
                    output += normalSymbols[ctr];
            }
            cryptLetter = "";
        }
        if ((character == ' ') && (right == ' ')) {
            output += " ";
        }
        pointer++;
    }
    return output;
}

I tend to prefer curly braces on their own lines, but that's a matter of choice and putting them at the end of the line is absolutely fine, but there should be a space before that opening curly brace. There's spaces added in many places that really improve clarity and readability.

There isn't a competent programmer on the planet that wouldn't rather work on the code as I indented it, nor a single one that would think your indentation is acceptable. If I was a teacher marking that, you'd lose points.

You're making extra work for us when we help you because we need to either put in extra effort to figure out the code structure, or re-indent it so it's readable. You can see where we'd be less inclined to want to help you in those circumstances. Help us help you.

Ok, point taken. Frankly I didn't think it was that big of a deal; unfortunately my professor is rather incompetent so I have to come to these forums for help. I appreciate your comments on the matter.
 
  • #7
matumich26 said:
Ok, point taken. Frankly I didn't think it was that big of a deal; unfortunately my professor is rather incompetent so I have to come to these forums for help. I appreciate your comments on the matter.

Poor you... Poor teachers are a pretty big barrier to learning well. Well, we're always here for you. At least there's that! :biggrin:

You might be interested in this site that provides pretty good online documentation on the C++ standard libraries:

http://www.cplusplus.com/reference/

About removing that member variable. You could add the string to be processed as a parameter to the function. Something like:

Code:
class crypt {
    public:
        crypt();
        string decode(string input);
        string encode(string input);
};

On the other hand, that makes using a class here kind of pointless anyways since it doesn't need to keep any state information. There's no need to even instantiate a class for this job. Could just define two functions in a namespace, but I won't get into that right now. Your teacher probably expects a class, and likely hasn't covered namespaces, so I wouldn't worry about that aspect yet.

Oh yeah, I'm wrong about 'stringbuffer' (it happens). Don't know why I was thinking that. Probably just doing too much Java. :rofl:

Using 'string' is indeed the right thing to do here. Carry on. :biggrin:
 

1. What is "decoding" and "encoding" in the context of messages?

Decoding refers to the process of translating a message from a code or cipher back into its original form. Encoding is the opposite process, where a message is converted into a code or cipher for security or secrecy purposes.

2. Why would a message need to be encoded in the first place?

Messages may be encoded to protect sensitive information, prevent unauthorized access, or ensure that the message is only understood by its intended recipient.

3. How can I decode a previously encoded message?

The first step in decoding a message is to identify the type of code or cipher used. Then, you can use various decoding techniques such as frequency analysis, letter substitution, or pattern recognition to decipher the message.

4. Is there a universal method for decoding any type of message?

No, there is no one-size-fits-all method for decoding messages. Different codes and ciphers require different techniques for decoding, and some may be more complex than others.

5. Can a previously encoded message be decoded without the key?

It depends on the type of code or cipher used. Some codes, such as simple letter substitution, can be decoded without the key. However, more complex codes and ciphers, such as the Enigma machine used in World War II, cannot be decoded without the key or specific knowledge of the code.

Similar threads

  • Engineering and Comp Sci Homework Help
Replies
14
Views
2K
  • Engineering and Comp Sci Homework Help
Replies
5
Views
2K
  • Programming and Computer Science
Replies
8
Views
5K
  • Engineering and Comp Sci Homework Help
Replies
1
Views
2K
  • Engineering and Comp Sci Homework Help
Replies
3
Views
2K
  • Engineering and Comp Sci Homework Help
Replies
7
Views
2K
  • Programming and Computer Science
Replies
2
Views
3K
  • Engineering and Comp Sci Homework Help
Replies
15
Views
2K
  • Engineering and Comp Sci Homework Help
Replies
5
Views
2K
  • Engineering and Comp Sci Homework Help
Replies
8
Views
6K
Back
Top