Home > Net >  Decode cipher into message function not working properly
Decode cipher into message function not working properly

Time:10-08

I'm writing a substitute cipher program which receives a user inputed string, which it then ciphers using a read only array.

const int ARRAY_SIZE = 26;                                                        //10
const char cipher[ARRAY_SIZE] = {'B', 'T', 'N', 'M', 'X', 'W', 'E', 'V', 'L', 'K', 'P', 'Q', 'C', 'R', 'J', 'Y', 'Z', 'D', 'A', 'F', 'H', 'I', 'G', 'S', 'U', 'O'};

As you can see, this is the cipher I'm using. The //10 is just the index of that char, so I can keep track of it easier.

This is my encode function, it encodes the user inputed string according to my cipher. This works and the logic I've highlighted in the comment in the codeblock.

'Hello' turns into 'VXQQJ' for example.

string encodeText(string plaintext, const char ciph[])
{
    for (int i = 0; i <= plaintext.length();   i)
    {
        plaintext[i] = toupper(plaintext[i]);
        if ((plaintext[i] >= ('A')) && (plaintext[i] <= ('Z')))
            plaintext[i] = ciph[plaintext[i] - ('A')];
    }
    return plaintext;

    /*  H E L L O (NORMAL ASCII)
    *   V X Q Q J (OUR ENCODING)
    *   0 1 2 3 4 
    * 
    *   72(H)     = ciph[72 - 65] = ciph[7]  ->V  
    *   69(E)     = ciph[69 - 65] = ciph[4]  ->X
    *   76(L)     = ciph[76 - 65] = ciph[11] ->Q
    *   76(L)     = ciph[76 - 65] = ciph[11] ->Q
    *   79(O)     = ciph[79 - 65] = ciph[14] ->J
    */
}

However, I'm unable to decode VXQQJ for example, back into HELLO. I've tried to write this function, which is the inverse of the encodeText function

string decodeText(string encodedText, const char ciph[])
{
    for (int i = 0; i <= encodedText.length();   i)
    {
        encodedText[i] = toupper(encodedText[i]);
        if ((encodedText[i] >= 65) && (encodedText[i] <= 90))
            encodedText[i] = ciph[encodedText[i] /* NO CLUE */];
    }
    string decodedPlaintext = encodedText;
    return decodedPlaintext;
}

I tried figuring out a similar pattern to encodeText, however it doesn't work, I need to subtract arbitrary values from my cipher to get the correct index. I also tried implementing a decipher const array, which stores all chars 'A' - 'Z' and somehow use that to decode it, yet that isn't correct either.

Here is my entire program, for ease of reference:

#include <iostream>
using namespace std;
#define endl "\n";

/*
*   Substitution cipher problem
*   All messages are made of uppercase, lowercase letters and punctuation.
*   The original message is called the 'plaintext'
*   The cipher is created by substituting each letter with another letter.
*   Hard code a const array of 26 char elements for the cipher.
*   Read a plaintext message and output ciphertext.
*   
*   Then we decipher the encoded message again to check it's validity.
*/

//B T N M X W E V L K P Q C R J Y Z D A F H I G S U O from https://www.dcode.fr/deranged-alphabet-generator

string encodeText(string plaintext, const char cyph[])
{
    for (int i = 0; i <= plaintext.length();   i)
    {
        plaintext[i] = toupper(plaintext[i]);
        if ((plaintext[i] >= ('A')) && (plaintext[i] <= ('Z')))
            plaintext[i] = cyph[plaintext[i] - ('A')];
    }
    return plaintext;

    /*  H E L L O (NORMAL ASCII)
    *   V X Q Q J (OUR ENCODING)
    *   0 1 2 3 4 
    * 
    *   72(H)     = ciph[72 - 65] = ciph[7]  ->V  
    *   69(E)     = ciph[69 - 65] = ciph[4]  ->X
    *   76(L)     = ciph[76 - 65] = ciph[11] ->Q
    *   76(L)     = ciph[76 - 65] = ciph[11] ->Q
    *   79(O)     = ciph[79 - 65] = ciph[14] ->J
    */
}

string decodeText(string encodedText, const char cipher[])
{
    for (int i = 0; i <= encodedText.length();   i)
    {
        encodedText[i] = toupper(encodedText[i]);
        if ((encodedText[i] >= 65) && (encodedText[i] <= 90))
            encodedText[i] = cipher[encodedText[i] /* NO CLUE */];
    }
    string decodedPlaintext = encodedText;
    return decodedPlaintext;
}

int main(void)
{
    const int ARRAY_SIZE = 26;                                                        //10
    const char cipher[ARRAY_SIZE] = {'B', 'T', 'N', 'M', 'X', 'W', 'E', 'V', 'L', 'K', 'P', 'Q', 'C', 'R', 'J', 'Y', 'Z', 'D', 'A', 'F', 'H', 'I', 'G', 'S', 'U', 'O'};
    //                                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
    cout << "Enter plaintext string" << endl;
    string plaintext;
    getline(cin, plaintext);
    string encoded = encodeText(plaintext, cipher);
    cout << "The encoded text is:" << ' ' << encoded << endl;

    cout << "Please enter the encoded text to verify if it is correct or not" << endl;
    string encodedText;
    getline(cin, encodedText);
    string decoded = decodeText(encodedText, cipher);
    cout << "The decoded text is" << ' ' << decoded << endl;

    return 0;
}

CodePudding user response:

For decoding, you need to have a reverse mapping (for example a data structure which will map 'V' back to 'H' and so on), or for every encoded character search and find 'V' in cipher and use its index to obtain the decoded character.

Take the following code for example:

#include <iostream>

using namespace std;

int main(void)
{
    const string cipher = "BTNMXWEVLKPQCRJYZDAFHIGSUO";
    const int cipherSize = cipher.length();

    //Build the reverse mapping once:
    size_t reverseCipher[cipherSize];
    for (int i = 0; i < cipherSize;   i)
        reverseCipher[i] = cipher.find((char) ('A'   i)); //Get the index of each letter of the alphabet from cipher.

    string str = "HELLOCIPHER"; //Should be replaced with user's input.
    cout << "Plain: " << str << endl;

    //Encoding:
    const int strLen = str.length();
    for (int i = 0; i < strLen;   i)
        str[i] = cipher[str[i] - 'A'];
    cout << "Encoded: " << str << endl;

    //Decoding:
    for (int i = 0; i < strLen;   i)
        str[i] = 'A'   reverseCipher[str[i] - 'A'];
    cout << "Decoded: " << str << endl;

    return 0;
}
  • Related