将密码解码为消息功能无法正常工作

Decode cipher into message function not working properly

我正在编写一个替代密码程序,它接收用户输入的字符串,然后使用只读数组对其进行加密。

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'};

如您所见,这是我使用的密码。 //10 只是该字符的索引,因此我可以更轻松地跟踪它。

这是我的编码函数,它根据我的密码对用户输入的字符串进行编码。这有效,我在代码块的评论中强调了逻辑。

例如

'Hello'变成'VXQQJ'。

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
    */
}

但是,例如,我无法解码 VXQQJ,返回 HELLO。 我试过写这个函数,它是 encodeText 函数的反函数

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;
}

我尝试找出与 encodeText 类似的模式,但它不起作用,我需要从我的密码中减去任意值以获得正确的索引。我还尝试实现一个 decipher const 数组,它存储所有字符 'A' - 'Z' 并以某种方式使用它来解码它,但这也不正确。

下面是我的整个程序,方便参考:

#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;
}

为了解码,你需要有一个反向映射(例如一个数据结构将 'V' 映射回 'H' 等等),或者对于每个编码字符搜索并找到 'V' in cipher 并使用其索引获取解码后的字符。

以下面的代码为例:

#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;
}