如何 ROT 加密包含空格的字符串?



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

例如:

"你好朋友"会加密得很好,但是,

"你好,我的朋友"不会。

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

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

所以,很明显?我正在索引一个索引错误的数组。如果是这样的话,我在哪里做?

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

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

它抛出异常:"Projekt 01 (ÖBO1 - PROG1) 中0x0FD9CAB6 (ucrtbased.dll) 未处理的异常.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) << "nn";
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;
}

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

考虑当_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少一个,因为我们假设输入中只有一个空格字符。

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

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末尾,这导致了崩溃,至于我们可以从0索引到n-1的长度n字符串。这是您遇到的问题。

对于n空间,外部 for 循环的最终迭代的条件如下所示:

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

因此,代码甚至在最终迭代之前就可能崩溃。

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

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

最新更新