为什么我的代码打印错误的密文?

时间:2019-05-14 03:46:43

标签: c++ encryption codeblocks

我正在尝试制作一个程序,通过在每个字母前加十个字母来将字符串转换为加密。 https://gyazo.com/86f9d708c2f02cf2d70dbc1cd9fa9a06我正在做第2部分。当我输入“ helloworld”时,出现0x45之类的东西。请帮忙!这是即将到期!

我尝试弄乱for循环,但没有帮助。

#include <iostream>

using namespace std;

int main()
{
    //Input Message
    cout << "Enter a message" << endl;
    string message;
    getline(cin, message);

    //Convert Message to Numbers
    int numMess[message.length()];
    for (int i = 0; i<message.length(); i++) {
        numMess[i] = (int)message[i];
    }

    cout << numMess << endl;

    //Encrypt Number Message by adding ten to each one
    int encryptNumMess[message.length()];
    for (int a = 0; a < message.length(); a++){
        encryptNumMess[a] = numMess[a] + 10;
        if (encryptNumMess[a] > 122) {
            encryptNumMess[a] = 97;
        }
    }
    cout << encryptNumMess << endl;

    //Convert Encrypted Number Message to letters
    string encryption[message.length()];
    for (int b = 0; b<message.length(); b++) {
        encryption[b] = (char)encryptNumMess[b];
    }

    cout << encryption << endl;
    return 0;
}

我希望当我输入“ helloworld”时,最终产品将是“ rovvygybvn”。

3 个答案:

答案 0 :(得分:2)

如果您愿意放弃手工编码的循环,则可以使用std::transform之类的STL算法来完成此操作:

但是首先,您应该做一些事情:

请勿使用幻数,例如122、97等。而应使用实际的字符常量,例如ab等。但是,如果我们假设使用ASCII,则字母字符代码是连续的,您的特定程序可以简单地使用常量字符串来表示字母,然后使用简单的索引来选择字符。

const char *alphabet = "abcdefghijklmnopqrstuvwxyz";

然后获取字母a,只需简单的减法即可获取索引:

char ch = 'b';
int index = ch - 'a'; // same as 'b' - 'a' == 98 - 97 == 1
std::cout << alphabet[index]; // will print 'b'

鉴于此,接下来的事情是弄清楚如果将值加10,然后到达字母的开头,则得出哪个字符。可以使用模数(除法后的余数)完成

char ch = 'x';
int index = (ch - 'a' + 10) % 26; // Same as ('x' - 'a' + 10) % 26 == (120 - 97 + 10) % 26  == 33 % 26 == 7
std::cout << alphabet[index]; // will print 'h'

接下来的事情是找出相反的情况,在给定加密字符的情况下,您必须通过减去10来找到未加密的字符。这里采用了相反的方式,因此需要做更多的工作(未显示,但代码示例反映了已完成的操作。

将所有内容放在一起,并使用std::transform和lambda,我们得到以下小程序:

#include <iostream>
#include <algorithm>
#include <string>
#include <iterator>
#include <cmath>

int main()
{
    //Input Message
    const char *alphabet="abcdefghijklmnopqrstuvwxyz";
    std::string message = "helloworld";
    std::string result;

    // set the encrypted string using the formula above and std::transform
    std::transform(message.begin(), message.end(), std::back_inserter(result),
                  [&](char ch) { return alphabet[(ch - 'a' + 10) % 26]; });
    std::cout << "Encrypted: " << result << '\n';  

    // convert back to unencrypted using the above formula and std::transform
    std::string result2;
    std::transform(result.begin(), result.end(), std::back_inserter(result2),
                  [&](char ch) 
                  { int index = ch - 'a' - 10;  index = index < 0?26 - (abs(index) % 26):index % 26; return alphabet[index];});
    std::cout << "Unencrypted: " << result2;                  
}

输出:

 Encrypted: rovvygybvn
 Unencrypted: helloworld

答案 1 :(得分:1)

此代码可用于加密,如果您想解密,则应颂扬newAlphabetoldAlphabet

我在newAlphabetoldAlphabet用于加密以及用于解密的代码中进行注释

#include <windows.h>
#include <stdio.h>
#include <string>
#include <iostream>
using namespace std;

int main()
{
    // For Encrypt
    string newAlphabet = "abcdefghijklmnopqrstuvwxyz";
    string oldAlphabet = "klmnopqrstuvwxyzabcdefghij";

    // For Decrypt
    //string newAlphabet = "klmnopqrstuvwxyzabcdefghij";
    //string oldAlphabet = "abcdefghijklmnopqrstuvwxyz";


    string input = "";
    string output = "";

    getline(cin, input);
    int inputLen = input.size();

    if (oldAlphabet.size() != newAlphabet.size())
        return false;

    for (int i = 0; i < inputLen; ++i)
    {
        int oldCharIndex = oldAlphabet.find(tolower(input[i]));

        if (oldCharIndex >= 0)
            output += isupper(input[i]) ? toupper(newAlphabet[oldCharIndex]) : newAlphabet[oldCharIndex];
        else
            output += input[i];
    }
    cout << output << endl;
    return 0;
}

答案 2 :(得分:0)

正如其他人已经提到的,int numMess[message.length()];不是有效的c ++。 如果它适合您,那么您正在使用编译器扩展,您实际上不应依赖它。正确的方法是:

std::vector <int> numMess(message.length());

查找std::vector reference以获得更多信息。

接下来,int encryptNumMess[100];创建一个C数组样式数组。 encryptNumMess是指向数组的基本指针。当您尝试std::cout << encryptNumMess时,它将输出指针值,而不是数组。为此,您需要一个for循环:

for(int i = 0; i < 100; ++i)
    std::cout << encryptNumMess[i] << " ";
std::cout << endl;

当您像使用numMess一样将其转换为向量时,上面的方法也适用,而在这种情况下,std::cout << encryptNumMess甚至无法编译。

第三,string encryption[100]创建了一个由100个字符串组成的数组!不是大小为100的字符串。为此:

std::string foo(message.length(), '\0');

我们必须指定用什么字符填充字符串。因此,我们'\0'。 现在,要输出该字符串,可以使用std::cout << foo

最后,由于char允许进行算术运算,因此整个程序可能会缩短为这样

#include <iostream>

int main()
{
    // Input Message
    std::cout << "Enter a message" << std::endl;
    std::string message, encryption;
    getline(std::cin, message);

    // Resize encryption string to the desired length
    encryption.resize(message.length());

    // Do the encryption
    for(size_t i = 0; i < message.length(); ++i) {
        encryption[i] = message[i] + 10;
        if (encryption[i] > 122) {
            encryption[i] = 97;
        }
    }

    // Output the string
    std::cout << encryption << std::endl;

    return 0;
}

当然,按照说明,您的加密算法仍然不正确,但是我会留给您找出答案。我相信@PaulMcKenzie已经告诉了您大多数解决方法,并且也不要使用幻数。