如何ROT加密带有空格的字符串?

时间:2018-01-18 19:47:59

标签: c++ encryption

我目前正在开发一个小程序,提示用户输入他们想要的任何文本,然后使用ROT-n方法对其进行加密。截至目前,我可以加密由随机字母,单词和数字组成的字符串。但问题是,我无法加密其中包含空格的字符串。

例如:

“hellomyfriend”会加密,但是,

“你好我的朋友”不会。

弹出一个错误窗口,显示一些文字和这个特定部分

“表达式:字符串下标超出范围”。

显然,很明显?我正在索引一个索引不好的数组。如果是这样的话,我在哪里这样做?

当我点击“确定”时,程序会在加密函数中的内部for循环中抛出异常

if (_user_text[i] == _alphabet[j])

它抛出异常:“Projekt 01中的0x0FD9CAB6(ucrtbased.dll)处于未处理的异常(ÖBO1 - PROG1).exe:将无效参数传递给认为无效参数致命的函数。”

所以我假设问题是if (_user_text[i] == _alphabet[j])在某处?

开始:

void uppgift_2() {

    // Uppgift:
    // Du skall skapa en enkel kryptering. Låt användaren mata in en text av typen string, valfri storlek.
    // Skriv sedan ut en krypterad version av strängen med rot3.

    // Array with the alphabet in it
    char alphabet[36] = { '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', 
                            '0', '1', '2', '3', '4', '5', '6', '7', '8', '9'};

    // Variables
    std::string user_text = "", org_string = "";
    std::string temp = "";
    int rot_x = 7; // rot7

    // Prompt user for input
    std::cout << "| Enter in a random text (english): ";
    getline(std::cin, user_text);
    org_string = user_text;

    // Make string lowercase
    for (unsigned int b = 0; b < user_text.length(); b++) {
        char lower_Version = tolower(user_text[b]);
        temp += lower_Version;
    }
    user_text = temp;

    // Encrypting user entered text...
    std::string _encrypted_text = encrypt_string(user_text, alphabet, rot_x);

    // Prints out the original string, the encrypted version and the final decrypted version
    std::cout << "\n| Original version: " << org_string << std::endl;
    std::cout << "| - - - - - - - - - - - - - - - - - - - - - - - - - - - |\n" << std::endl;
    std::cout << "| Encrypted version: " << _encrypted_text << std::endl;
    std::cout << "| Decrypted version: " << decrypt_string(_encrypted_text, alphabet, rot_x) << "\n\n";

    system("PAUSE");
    main_menu(); // Sends the user back to the main menu

}

加密功能:

std::string encrypt_string(std::string &_user_text, char(&_alphabet)[36], int &rot_x) {

    // Variable(s)
    std::string encrypted_text = "";
    int array_len = 35;
    int pointer = 0; // Used to determine if a switch from rot7 to rot13 is needed

    // The outer loop goes through each character of the user entered string
    for (int i = 0; encrypted_text.length() < _user_text.length(); i++) {
        // The inner loop finds the correspondent character from the alphabet and uses rot7 or rot13 on it
        for (int j = 0; j <= array_len; j++) {
            // if (selected character from user string) is equal to (the correspondant character in the alphabet)
            if (_user_text[i] == _alphabet[j]) {
                int alphabet_index = (j + rot_x);
                // Checks if alphabet_index is out of range and adjusts accordingly
                if (alphabet_index >= array_len+1) {
                    alphabet_index -= array_len+1;
                }
                // Saves the decrypted character...
                char encrypted_char = _alphabet[alphabet_index];
                // ... and concatenates it to the decrypted string
                encrypted_text += encrypted_char;
                break; // Breaks out of inner loop and lets outer loop get the next character
            }
        }
        pointer++;
        // If five characters have been encrypted, switch to rot13
        if (pointer == 5) {
            rot_x = 13;
        }
        // Go back to rot7 when yet another 5 characters have been encrypted
        else if (pointer == 10) {
            rot_x = 7;
            pointer = 0; // Reset the pointer
        }
    }

    // Returns the final encrypted text
    return encrypted_text;

}

1 个答案:

答案 0 :(得分:0)

首先,为了使解释更简单,我们假设输入文本中只有一个空格字符,尽管这种推理仍然适用于具有多个空格字符的输入。

考虑_user_text[i]是空格字符时内部for循环会发生什么。由于_alphabet不包含空格字符,_alphabet[j]永远不会等于_user_text[i]中的空格字符。因此,内部for循环if块内的代码不会被执行,更重要的是,encrypted_text += encrypted_char永远不会执行。

然后外部for循环将继续执行,然后一旦到达该迭代结束,计数器变量i将递增。但是,encrypted_text.length()未更改,因为我们从未将encrypted_char附加到encrypted_text。这意味着encrypted_text.length()现在等于i-1。如果我们继续迭代,encrypted_text.length()将保持小于i,因为我们假设输入中只有一个空格字符。

在循环的最后一次迭代中,这会产生一个问题。如果我们将encrypted_text.length()替换为i-1,因为我们发现它们在最后一次迭代中是相同的:

for (int i = 0; i - 1 < _user_text.length(); i++)

我们可以在<符号的两边添加一个以获得以下内容:

for (int i = 0; i < _user_text.length() + 1; i++)

由于i始终小于_user_text.length() + 1,因此循环最后一次迭代的值为_user_text.length()。这意味着对于外部循环的最后一次迭代,下面是条件:

if (_user_text[i] == _alphabet[j])

与:

相同
if (_user_text[_user_text.length()] == _alphabet[j])

这是导致崩溃的_user_text结束时的索引,对于长度为n的字符串,我们可以从0索引到n-1。这是您遇到的问题。

对于n个空格,外部for循环的最后一次迭代的条件如下所示:

for (int i = 0; i < _user_text.length() + n; i++)

所以代码甚至可能在最后一次迭代之前崩溃。

为了能够加密空格字符,您需要:

  1. ' '添加到alphabet中的uppgift_2数组,并将其大小更改为37
  2. _alphabetencrypt_string数组参数的大小更改为37
  3. 最后,将array_len中的encrypt_string更改为36