我正在为我的C ++项目制作一个密码程序。我的方法是声明和初始化两个字符串,第一个为alphabet
,另一个为key
,如下所示。
string alphabet {"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"};
string key {"ZYXWVUTSRQPONMLKJIHGFEDCBAzyxwvutsrqponmlkjihgfedcba"};
我想在密码中将所有这52个字母互相配对。也就是说,将小a
替换为大写Z
,将小b
替换为Y
,依此类推。
将提示用户输入一个字符串,该字符串将存储在input
中。我的想法是循环遍历input
字符串并将其与alphabet
匹配,从而在key
字符串中找到其对。这很容易,因为两对将具有相同的索引。但是,如何交换它们?我可以在swap(input[i], key[i])
中使用循环,但这只会使每个字符串成为ZYXW...
,因此我无法在此处编写逻辑...下面是到目前为止的全部代码。
#include <iostream>
#include <string>
using namespace std;
int main()
{
string alphabet {"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"};
string key {"ZYXWVUTSRQPONMLKJIHGFEDCBAzyxwvutsrqponmlkjihgfedcba"};
int choice {};
cout<<"Welcome to the Cypher Program";
cout<<"\nYou can encode and decode your messages to make sure they remain secret!";
cout<<"\nWould you like to encode(Press 1) or decode(Press 2) a message?"<<endl;
cin>>choice;
//Encoding
if (choice == 1)
{
string input {};
cout<<"Enter a string to encrypt"<<endl;
getline(cin.ignore(), input); //testString
cout<<"Your encrypted message is: "<<endl;
for(int i {0}; i<input.length(); i++){
swap(input[i], key[i]);
}
cout<<input; //ZYXWVUTSRQ
}
return 0;
}
我真正想做的是:
alphabet
中找到其索引key
。 答案 0 :(得分:1)
步骤1:在原始字符串中查找字符的索引
if (input[i] >= 97)
{
index = input[i]-97;
}
else
{
index = (input[i]-65) + 26;
}
现在使用
input[i] = key[index];
答案 1 :(得分:1)
我将在这里讨论两种简单的方法。
首先要按照您的建议进行操作,从alhphabet
中找到字母的索引,然后使用该索引从key
中找到编码的字母。
在这里,您可以通过观察编码中的模式来使用一个简单的技巧。只要是大写字母,就可以从其ASCII值减去'A'
以获得offset
,然后从ASCII值z
减去该偏移量即可得到编码字母。当它是小写字母时,您会注意到类似的模式。
下面是这两种方法的示例代码。
#include <iostream>
#include <string>
using namespace std;
int main(){
string alphabet {"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"};
string key {"ZYXWVUTSRQPONMLKJIHGFEDCBAzyxwvutsrqponmlkjihgfedcba"};
string input1 {"testString"}, input2 {"testString"};
cout<<"Your encrypted message is (Approach 1) : "<<endl;
// Approach 1
for(int i {0}; i<input1.length(); i++){
int idx;
for(idx=0;idx<alphabet.length();idx++) // find index from alphabet
if(input1[i]==alphabet[idx])
break;
input1[i] = key[idx]; // replace with key
}
cout<<input1<<endl; //GVHGhGIRMT
// Approach 2
cout<<"Your encrypted message is (Approach 2) : "<<endl;
for(int i {0}; i<input2.length(); i++){
if(input2[i] >= 'A' && input2[i]<='Z')
input2[i] = 'z' - (input2[i]-'A');
else if(input2[i] >= 'a' && input2[i]<='z')
input2[i] = 'A' + ('z'-input2[i]);
}
cout<<input2; //GVHGhGIRMT
return 0;
}
输出
Your encrypted message is (Approach 1) :
GVHGhGIRMT
Your encrypted message is (Approach 2) :
GVHGhGIRMT
答案 2 :(得分:1)
嗯,您的原始代码还不错。您只需要用分配替换掉交换。这使您的原始数据保持不变。
input[i] = key[alphabet.find(input[i])];
您应该在{alphabet“和” key“之前添加const
,否则编译器将阻止您的代码。
顺便说一句,使用此对称密钥,编码和解码是相同的。
不确定为什么要写getline(cin.ignore(), input);
而不是getline(cin, input);
。那应该纠正。
计算方法的优点是密钥字符串将不在exe文件中。
您也可以使用XOR 255(result += input[i] ^255
(它会翻转所有位)或256-input [i];
使用std::transform
算法的“更现代”的C ++解决方案下面
#include <iostream>
#include <string>
#include <algorithm>
int main()
{
// The encoding alphabet and key
constexpr std::string_view alphabet{ "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ _" };
constexpr std::string_view key{ "ZYXWVUTSRQPONMLKJIHGFEDCBAzyxwvutsrqponmlkjihgfedcba_ " };
// String to encrypt
std::string message{"Hello world"};
// Here we will store the result
std::string result;
std::transform(message.begin(), message.end(), std::back_inserter(result), [&key, &alphabet](const char c)
{ size_t pos{ alphabet.find(c) }; return (pos != std::string::npos) ? key[pos] : '_'; });
// Show result
std::cout << "\nEncrypted: " << result << "\n";
message = result;
result.clear();
std::transform(message.begin(), message.end(), std::back_inserter(result), [&key, &alphabet](const char c)
{ size_t pos{ alphabet.find(c) }; return (pos != std::string::npos) ? key[pos] : '_'; });
// Show result
std::cout << "\nDecrypted: " << result << "\n";
return 0;
}