【问题标题】:Encryption with substitution cipher使用替换密码进行加密
【发布时间】:2020-05-08 18:24:09
【问题描述】:

我正在用字母表中的另一个字母替换字母表中的每个字母。 例如,每个“a”被替换为“Q”,每个“b”被替换为“W”。 我已经编写了代码来加密下面的句子。

#include<iostream>
#include<string>
#include<cctype>

using namespace std;

int main(){

    string alphabet {"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"};
    string key      {"QWERTYUIOPasdfghjklZXCVBNMqwertyuiopASDFGHJKLzxcvbnm"};

    string original {};
    string encrypted {};

    cout<<"Enter your secret message: ";
    getline(cin ,original);
    // cout<<"Encrypting message..."<<endl;

    for(int i=0;i<original.length();i++){
        if(isalpha(original.at(i)) == 1){
            encrypted.at(i) =  key.at(alphabet.find(original.at(i)));
        }
        else
            encrypted.at(i) = original.at(i);
    }

    cout<<"Encrypted message: "<<encrypted<<endl;
}

我正在更改字符串字母表中索引为 i 的每个字符,并使用键中相同索引的字符。 例如:- 如果原始字符串 = "Hello" 加密字符串应该是“iTssg”

但是当我运行这个程序时,我得到一个错误

输出: 输入你的秘密信息:你好 在抛出 'std::out_of_range' 的实例后调用终止 what(): basic_string::at: __n (0) >= this->size() (0)

谁能告诉我我应该对这段代码进行哪些更改?

【问题讨论】:

  • 你应该在这里探索std::unordered_map的使用。

标签: c++ string c++14


【解决方案1】:

您的encrypted 字符串为空,因此使用.at() 对其进行索引会引发异常。

要解决这个问题,你可以像这样追加字符:

 for(int i=0;i<original.length();i++){
        if(std::isalpha(original.at(i))){
           encrypted +=  key.at(alphabet.find(original.at(i)));
        }
        else 
           encrypted += original.at(i);
}

这是demo

或者,您可以确保encryptedoriginal 具有相同的大小,如下所示:

encrypted = original;

然后你的循环保持不变。

此外,您可以通过使用 range-for 循环来简化循环:

for(unsigned char c : original){
        if(std::isalpha(c)){
            encrypted +=  key.at(alphabet.find(c));
        }
        else
            encrypted += c;
    }

您可以通过结合这两种方法来进一步简化:

string encrypted = original;
for (auto &c : encrypted)
  if (std::isalpha(c))
    c = key.at(alphabet.find(c));

这是demo

【讨论】:

  • 但是如果替换你提到的第一个代码它会抛出同样的错误
  • 你得到的错误是什么字符串(代码行)?不能为encrypted
  • 另外,isalpha 的结果不应与1 进行比较。我已经在答案中解决了这个问题。
  • 不用担心。为答案添加了一个更简单的解决方案。