【问题标题】:Simple Encryption program array简单加密程序数组
【发布时间】:2021-10-08 22:13:04
【问题描述】:

构建一个简单的程序,将字符串中字符的 ASCII 值乘以 3 进行加密,然后除以 3 进行解密。到目前为止,我已经完成了加密部分,但是每当我输入加密给出的内容并尝试解密时,它都不起作用。我认为这与缓冲流有关,但如果有人能提供帮助,我可能是错的。

#include<iostream>
using namespace std;

int main()
{
string message;
int charValue;
int counter;
int encrypt;
char choice;
char quit = 'N';



while (quit == 'N')
{
    cout << "Enter E to encrypt or D to Decrypt\n";
    cin >> choice;
    toupper(choice);

    cout << "Enter text no spaces: ";
    cin >> message;

    int messagelen = message.length();
    string stringArray[255];

    if (choice == 'E')
    {
        for (counter = 0; counter < messagelen; counter++) //*3 to ascii val
        {
            stringArray[counter] = message[counter] * 3;

        }
        for (counter = 0; counter < messagelen; counter++)
        {
            cout << stringArray[counter];
        }
    }
    else
    {
        for (counter = 0; counter < messagelen; counter++) // divide 3 to ascii val
        {
            stringArray[counter] = message[counter] / 3;

        }
        for (counter = 0; counter < messagelen; counter++)
        {
            cout << stringArray[counter];
        }
    }
    cout << "\nY to go again N to quit";
    cin >> quit;

}
return 0;
}

【问题讨论】:

  • string stringArray[255]; 这将创建一个包含 255 个字符串的数组。这没有任何意义,因为您在输入时只接受一个字符串。您更可能需要的是 ints 数组(shortunsigned short 也足够大)。将 message[counter] * 3 存储在该数组的每个适当索引处,然后您可以除以 3 并强制转换为 char 以检索 ASCII 值。
  • 鉴于在编译时字符串的长度是未知的,使用std::vector&lt;unsigned short&gt; 可能更有意义。
  • 另外值得注意的是,您的 while 循环在 quit == 'N' 时运行,但您提示用户输入 'N' 以退出。

标签: c++ encryption


【解决方案1】:

这是一个有效的实现,尽管我同意另一个答案,即您应该使用 encryptdecrypt 函数。我在您的代码中发现了很多其他错误。您应该使用-Wall -Werror 启用所有警告并修复它们:

#include <iostream>
#include <vector>
#include <sstream>

int main()
{
  // removed some unused variables
  std::string message;
  size_t counter;
  char choice;
  char quit;
  // use vector of int instead of array of strings
  std::vector<int> encryptArray;

  // change to do while loop. Not particularly necessary, but I think
  // it makes more sense in this case. Your condition is broken. If the
  // user enters 'Y' at the end to go again, then the quit == 'N'
  // condition is false and the program terminates.
  do
  {
    std::cout << "Enter E to encrypt or D to Decrypt\n";
    std::cin >> choice;
    // toupper returns a value, you need to assign it to choice.
    // Not capturing the return value makes this a noop.
    choice = toupper(choice);

    if (choice == 'E')
    {
      std::cout << "Enter text no spaces: ";
      std::cin >> message;

      size_t messagelen = message.length();
      // initialize vector to input message length size
      encryptArray = std::vector<int>(messagelen);

      for (counter = 0; counter < messagelen; counter++) //*3 to ascii val
      {
        encryptArray[counter] = message[counter] * 3;
      }

      // Note, this 2nd loop is more work than you need, you could
      // simply put the std::cout line in the loop above below the
      // assignment
      for (counter = 0; counter < messagelen; counter++)
      {
        // added the separator just for clarity. You could also print
        // hex bytes
        std::cout << encryptArray[counter] << "|";
      }
    }
    else
    {
      // all the data we care about is in the vector now
      for (counter = 0; counter < encryptArray.size(); counter++) // divide 3 to ascii val
      {
        // you don't want to /3 what's in the message here, you want
        // to /3 the encrypted values, which are in the vector
        encryptArray[counter] = encryptArray[counter] / 3;
      }
      // plenty of ways to convert the vector to a string, this is not
      // a "modern" way.
      // Note, you could skip this loop entirely, and in the one
      // above, simply do ss << (char)(encryptArray[i] / 3);
      // Not necessary to write the data back to encryptArray first.
      std::stringstream ss;
      for (size_t i=0; i<encryptArray.size(); ++i)
      {
        ss << (char)encryptArray[i];
      }
      std::cout << "decrypted string: " << ss.str() << std::endl;
    }

    std::cout << "\nY to go again N to quit: ";
    std::cin >> quit;
  } while(quit != 'N'); // loop until quit == N

  return 0;
}

最后,我删除了using namespace std;here's why

在 Godbolt 上使用 stdin 会变得异常顺畅,但这里有一个 working demonstration,至少在最初是这样。

【讨论】:

    【解决方案2】:

    它将真正帮助您将其分解为更小的问题。让我们将std::string“加密”成std::vector&lt;int&gt;

    std::vector<int> encrypt_msg(std::string s) {
        std::vector<int> v;
    
        for (auto ch = s.begin(); ch != s.end(); ch++) {
            v.push_back(static_cast<int>(*ch) * 3);
        }
    
        return v;
    }
    

    然后让我们“解密”一条消息,反向执行转换。

    std::string decrypt_msg(std::vector<int> v) {
        std::string s;
    
        for (auto i : v) {
            s += static_cast<char>(i / 3);
        }
    
        return s;
    }
    

    现在您可以测试并查看您的各个功能做一件事是否有效,并且将整个程序放在一起应该会容易得多。

    【讨论】:

      猜你喜欢
      • 2014-09-05
      • 1970-01-01
      • 2015-01-17
      • 2010-09-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多