我一直在用C ++写一个非常基本的加密程序,要求用户输入一条消息,然后输入一个与消息中字符数相同的数字。然后它将消息中的每个字符转换为ascii数字,然后将数字中的每个数字添加到ascii,然后转换回字符并返回加密的字符串。并且进展与解密相反。当我试图加密“你好”时,我得到了 。有人可以解释我怎么解决这个问题?我还没有完成代码,但到目前为止这是:
#include <iostream>
using namespace std;
string encryptMsg(string msg)
{
cout << "Enter a number that is " << msg.length() << " digits long: ";
string codekey;
cin >> codekey;
char msgArr[msg.length()];
int keyCode[msg.length()];
int tempcount = 0;
for(char& c : msg) {
msgArr[tempcount] = c;
tempcount++;
};
tempcount = 0;
for(char& c : codekey) {
keyCode[tempcount] = c;
tempcount++;
};
double tempascii;
for(int i = 0; i < (sizeof(msgArr)/sizeof(msgArr[0])); i++)
{
tempascii = msgArr[i];
tempascii = tempascii + keyCode[i];
msgArr[i] = tempascii;
};
string outmsg;
for(int i = 0; i < (sizeof(msgArr)/sizeof(msgArr[0])); i++)
{
outmsg = outmsg + msgArr[i];
};
return outmsg;
}
string decryptMsg(string msg)
{
char msgArr[msg.length()];
int tempcount = 0;
for(char& c : msg) {
msgArr[tempcount] = c;
tempcount++;
};
double tempascii;
for(int i = 0; i < (sizeof(msgArr)/sizeof(msgArr[0])); i++)
{
tempascii = msgArr[i];
tempascii = tempascii - 3;
msgArr[i] = tempascii;
};
string outmsg;
for(int i = 0; i < (sizeof(msgArr)/sizeof(msgArr[0])); i++)
{
outmsg = outmsg + msgArr[i];
};
return outmsg;
};
int main()
{
string mode;
string msg;
cout << "Encryption Program" << endl;
cout << "Would you like to encrypt or decrypt?" << endl;
cin >> mode;
if (mode == "encrypt" || mode == "Encrypt" || mode == "ENCRYPT" || mode == "1")
{
cout << "Encryption. ENTER MSG HERE: ";
cin >> msg;
cout << encryptMsg(msg);
} else if (mode =="decrypt" || mode == "Decrypt" || mode == "DECRYPT" || mode == "2")
{
cout << "Decryption. ENTER MSG HERE: ";
cin >> msg;
cout << decryptMsg(msg);
};
return 0;
}
谢谢。
答案 0 :(得分:0)
使用cin
读取数据时存在许多潜在问题。如果您的任何输入包含空格(有意或无意),则代码会中断。 (如果使用不消耗前导空格的类型,例如char
,则会出现相同的情况)更好地使用面向行的输入(例如getline
)来读取用户输入通过按 Enter 确保您生成的'\n'
被读取并丢弃。
您的代码缺乏任何有意义的验证。您必须验证所有用户输入以确保没有遇到流错误,用户没有通过使用 Ctrl + C (或 Ctrl + Z)生成手动EOF
来取消输入在Windows上 - 但请参阅:CTRL+Z does not generate EOF in Windows 10)
此外,如果您要将数字读入您将依赖加密的字符串,则需要验证读入codekey
的每个字符实际上是一个数字。 (<cctype>
中的函数,如isdigit()
可以提供帮助)。
正如评论中所解释的那样char msgArr[msg.length()];
是错误的。 C ++标准不包括C标准那样的可变长度数组(VLA)。 gcc提供VLA作为标准的扩展,但这使您的代码不可移植。
如果您只想在msg
就地加密字符,则encryptMsg
中不需要任何其他字符串或存储空间 - 只需将您的数字添加到{{1}中的字符中}} 到位。例如,您可以执行以下简单操作来就地加密msg
:
msg
要保留string encryptMsg(string& msg)
{
string codekey; /* string codekey, result */
const char *k; /* pointer to chars in codekey */
cout << "Enter a number that is " << msg.length() << " digits long: ";
if (!getline (cin, codekey)) { /* read codekey */
cerr << "error: invalid input - codekey\n";
exit (EXIT_FAILURE);
}
if (codekey.length() < msg.length()) { /* validate codekey length */
cerr << "error: insufficient number of digits entered.\n";
exit (EXIT_FAILURE);
}
k = codekey.c_str(); /* initialize k to 1st char in codekey */
for (char& c : msg) { /* loop over each char in msg */
if (!isdigit(*k)) { /* validate char is a digit */
cerr << "error: non-numeric input '" << *k << "'\n";
exit (EXIT_FAILURE);
}
c = c + (*k++ - '0'); /* add digit val to c, encrypting msg */
}
return msg; /* return encrypted result */
}
,您只需将msg
声明为outmsg
并指定string
,然后使用数字加密outmsg = msg;
中的字符输入outmsg
,例如
codekey
否则,C ++提供了使用string encryptMsg(string& msg)
{
string codekey, outmsg = msg; /* string codekey, outmsg */
const char *k; /* pointer to chars in codekey */
cout << "Enter a number that is " << msg.length() << " digits long: ";
if (!getline (cin, codekey)) { /* read codekey */
cerr << "error: invalid input - codekey\n";
exit (EXIT_FAILURE);
}
if (codekey.length() < msg.length()) { /* validate codekey length */
cerr << "error: insufficient number of digits entered.\n";
exit (EXIT_FAILURE);
}
k = codekey.c_str(); /* initialize k to 1st char in codekey */
for (char& c : outmsg) { /* loop over each char in msg */
if (!isdigit(*k)) { /* validate char is a digit */
cerr << "error: non-numeric input '" << *k << "'\n";
exit (EXIT_FAILURE);
}
c += (*k++ - '0'); /* add digit val to c, encrypting msg */
}
return outmsg; /* return encrypted outmsg */
}
和new
的简单分配,或者您只需使用delete
进行string
- 但是您需要一个迭代器来帮助迭代codekey
中的字符,同时迭代codekey
中的字符。这取决于你,但在这些情况下,我找到了一个简单的分配结果消息,并使用一个简单的字符指针填充加密的字符串,然后分配给msg
返回就像其他任何东西一样简单,例如< / p>
string
您可以将一个简短的示例程序放在一起以验证加密,以确保它正在执行您打算执行的操作。下面,我们输入string encryptMsg(string& msg)
{
char *tmp = new char[msg.length() + 1], /* allocate for length + 1 */
*p = tmp; /* pointer to tmp */
const char *k; /* pointer to use for key */
string codekey, res; /* string codekey, result */
cout << "Enter a number that is " << msg.length() << " digits long: ";
if (!getline (cin, codekey)) { /* read codekey */
cerr << "error: invalid input - codekey\n";
exit (EXIT_FAILURE);
}
if (codekey.length() < msg.length()) { /* validate codekey length */
cerr << "error: insufficient number of digits entered.\n";
exit (EXIT_FAILURE);
}
k = codekey.c_str(); /* initialize k to 1st char in codekey */
for (char& c : msg) { /* loop over each char in msg */
if (!isdigit(*k)) { /* validate char is a digit */
cerr << "error: non-numeric input '" << *k << "'\n";
exit (EXIT_FAILURE);
}
*p++ = c + (*k++ - '0'); /* add digit val to c, store in tmp */
}
*p = 0; /* nul-termiante tmp */
res = tmp; /* assign char array to string res */
delete[] tmp; /* free allocated memory */
return res; /* return encrypted result */
}
作为"hello"
,加密并使用msg
作为"11111"
来获取codekey
返回的预期"ifmmp"
,例如
encryptMsg
(注意:所有函数都会生成相同的输出,但最后两个#include <iostream>
#include <string>
#include <cctype>
#include <limits>
using namespace std;
string encryptMsg(string& msg)
{ ... }
int main (void) {
string mode, msg;
cout << "mode: ";
if (!getline (cin, mode)) { /* read mode (discarding trailing '\n') */
cerr << "error: invalid input - mode\n";
return 1;
}
for (char& c : mode) /* convert mode to lowercase */
c = tolower(c);
if (mode == "encrypt" || mode == "1") { /* check mode */
cout << "msg : "; /* prompt for msg */
if (!getline (cin, msg)) { /* read msg */
cerr << "error: invalid input - msg\n";
return 1;
}
/* output encrypted result */
cout << "res : " << encryptMsg(msg) << '\n';
}
}
保持不变)
在启用警告的情况下编译
对于您编译的所有代码,您希望使用警告已启用进行编译,对于gcc / g ++和clang,您可以使用msg
作为相当包容的警告集,clang还提供-Wall -Wextra -pedantic
。 VS(-Weverything
)使用cl.exe
其中/W#
为#
,它还提供1-4
(这实际上意味着全部),您可以停用特定的警告不希望报告/Wall
,其中/w####
是禁用警告的代码。在没有警告的情况下编译之前不要接受代码。
了解您所获得的任何警告,他们会指出具体问题以及可以找到问题的路线。 (g ++在产生过多的消息方面有点过分,但他们仍然确定了问题和线条)。通过倾听编译器试图告诉你的内容,你可以学到很多东西。
示例使用/输出
####
由于这看起来很像一个任务,你可以从这里解决实现的其余部分。如果您遇到问题,请在现有问题下方添加更新后的代码,我们很乐意为您提供帮助。