C ++加密程序不起作用

时间:2018-04-02 00:21:50

标签: c++ encryption

我一直在用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;
}

谢谢。

1 个答案:

答案 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 ++在产生过多的消息方面有点过分,但他们仍然确定了问题和线条)。通过倾听编译器试图告诉你的内容,你可以学到很多东西。

示例使用/输出

####

由于这看起来很像一个任务,你可以从这里解决实现的其余部分。如果您遇到问题,请在现有问题下方添加更新后的代码,我们很乐意为您提供帮助。