密码算法问题



任务:这个密码将每个字母移动多个字母。如果移位使你越过字母表的末尾,只需旋转回字母表的前面。

例如:字符串=";Abc Def Ghi 999-*%/&((";shift(您输入的数字(=1(可以是任何整数(

程序应该这样打印:Bcd Efg Hij-*%/&(([]

我用一个void函数做了这个操作,但当我尝试用字符串函数做同样的事情时,它并没有起作用。它只处理字符串的第一个元素,然后返回值。对于这种特殊情况我的程序打印成";Bbc Def Ghi 999-*%/&((";

有解决这个问题的办法吗?

#include <iostream>
#include <cmath>
using namespace std;
string Cipher(string password, int shift) {
char Uppercase[26] = { 'A','B','C' ,'D' ,'E' ,'F' ,'G' ,'H' ,'I' ,'J' ,'K' ,'L' ,'M' ,'N' ,'O','P' ,'Q' ,'R' ,'S' ,'T' ,'U' ,'V' ,'W' ,'X' ,'Y','Z' };
char Lowercase[26] = { 'a','b','c' ,'d' ,'e' ,'f' ,'g' ,'h' ,'i' ,'j' ,'k' ,'l' ,'m' ,'n' ,'o','p' ,'q' ,'r' ,'s' ,'t' ,'u' ,'v' ,'w' ,'x' ,'y','z' };
for (int i = 0; i < password.length(); i++) {
for (int k = 0; k < 26; k++) {
int add = shift + k;
if (password[i] == Uppercase[k]) {
for (int i = 0; add > 25; i++) { // controlling add isn't bigger than 25
add -= 25;
}
password[i] = Uppercase[add]; // converting each letter
}
else if (password[i] == Lowercase[k]) {
for (int i = 0; add > 25; i++) { // controlling add isn't bigger than 25 
add -= 25;
}
password[i] = Lowercase[add]; //converting each letter
}
else {
k = 25; // if element of string is different from letters, program goes to next element 
}
}
}
return password;
}
int main() {
cout << "Please enter an integer different from 0 and multiples of 25: ";
string password = "Abc def ghi 999 -*%/&()[]";
int shift;
cin >> shift;
cout<< Cipher(password, shift);
system("pause>0");
}

您的加密问题可以通过使用现代C++用一条语句来解决。

但因为这是先进的,我会详细解释。


让我们首先思考,做什么,然后如何实现。


什么:

  1. 只能转换字母字符
  2. 不得以未加密的方式输出任何字母字符(与输入相同(
  3. 在加密的情况下,应为加密信件保留原始信件的外壳。这意味着,如果位置5是大写字母,那么在加密字符串中,位置5的字母也应为大写
  4. 字母应按规定的数量移位

如何:

我们将首先使用isalpha函数检查原始字母是否为alpha字母。

因此,对于它是一个字母的情况,我们将检查该字母是大写还是小写。事实上,我们只检查它是否是大写字母。

因为如果不是,那么它一定是小写字母(因为它肯定是一个字母,我们之前检查过,如果不是大写,那么它就是小写(。对于此检查,我们使用isupper函数。

然后我们将执行轮班操作。并将情况考虑在内,转换回一封信。

我们假定ASCII。如果我们要将ASCII字母/字符转换为基于0的索引,我们需要执行以下操作:

如果我们在ASCII表中查看,那么我们会看到,"A"等于65,依此类推。因此,为了得到基于0的索引,我们从字母中减去65。然后我们得到一个介于0和25之间的索引值。

然后我们加上移位值。当然可能会发生溢流。但是,这可以简单地通过模26除法来校正。

所以:26->0、27->1、28->2等等。相当简单。但是,因为我们希望稍后再次收到一封信,我们将在这个结果上加65。

对于小写字母,我们将执行几乎相同的操作,但使用97作为字母"a"的偏移量。

然后,我们可以通过使用三元或条件运算符将所有东西都放在一个表达式中。

std::isalpha(c) ? std::isupper(c) ? (c - 65 + shift) % 26 + 65 : (c - 97 + shift) % 26 + 97 : c

这是的缩写

// Check if letter/character is alpha
if (std::isalpha(c)) {
// Now check for upper or lower case
if (std::isupper(c)) {
// The character is uppercase
c = (c - 65 + shift) % 26 + 65;
}
else {
// The character is lower case
c = (c - 97 + shift) % 26 + 97;
}
}
else {
// The character is not alpha
}

与一个衬垫相同,无差异

所以,首先,检查阿尔法。如果为true,则检查大写字母,如果为true则转换大写字母,否则转换小写字母。如果它不是字母,那么保持不变。

然后,我们将所有这些作为Lambda表达式嵌入到std::transform-语句中。有关描述,请参见此处。

对于整个转换过程,结果只有一条语句:

std::transform(password.begin(), password.end(), password.begin(), [shift](const char c)
{return std::isalpha(c) ? std::isupper(c) ? (c - 65 + shift) % 26 + 65 : (c - 97 + shift) % 26 + 97 : c; });

最后,我们构建了一个用于演示目的的小型驱动程序:

#include <iostream>
#include <string>
#include <algorithm>
#include <cctype>
int main() {
// Our password
std::string password = "Abc def ghi 999 -*%/&()[]";
// Give instruction to the user
std::cout << "nPlease enter a postive integer: ";
// Get number of shifts from user and check, if the value could be read
if (int shift{}; std::cin >> shift && shift > 0) {
// Now do the encryption
std::transform(password.begin(), password.end(), password.begin(), [shift](const char c)
{return std::isalpha(c) ? std::isupper(c) ? (c - 65 + shift) % 26 + 65 : (c - 97 + shift) % 26 + 97 : c; });
// Show the result to the user
std::cout << "nnEncrypted passphrase: t" << password << 'n';
}
else std::cerr << "nn*** Error: Problem with input!nn";
return 0;
}

而且,由于一行代码可能太高级了,让我们使用显式的、更详细的代码。只是为了完成:

#include <iostream>
#include <string>
#include <algorithm>
#include <cctype>
int main() {
// Our password
std::string password = "Abc def ghi 999 -*%/&()[]";
// Give instruction to the user
std::cout << "nPlease enter a postive integer: ";
// Get number of shifts from user and check, if the value could be read
if (int shift{}; std::cin >> shift && shift > 0) {
// --------------Can be written in one statement -----------------------
for (char& c : password) {
// Check if letter/character is alpha
if (std::isalpha(c)) {
// Now check for upper or lower case
if (std::isupper(c)) {
// The character is uppercase
c = (c - 65 + shift) % 26 + 65;
}
else {
// The character is lower case
c = (c - 97 + shift) % 26 + 97;
}
}
else {
// The character is not alpha
}
// ------------------------------------------------------------------
}
// Show the result to the user
std::cout << "nnEncrypted passphrase: t" << password << 'n';
}
else std::cerr << "nn*** Error: Problem with input!nn";
return 0;
}

在k循环中,您可以确定字母表中字母的索引。然而,当例如i=1时,则password[1]表示字母"b"。现在,从k==0开始k循环,其中Uppercase[0]Lowercase[0]分别表示"A"one_answers"A",您直接进入else条件,并且您的k循环终止而不执行任何操作(您设置k=25并递增它(。这里是一个固定的版本(注意,我还使用模运算符%来确保0 < add < 26:

#include <iostream>
#include <cmath>
using namespace std;
string Cipher(string password, int shift) {
char Uppercase[26] = { 'A','B','C' ,'D' ,'E' ,'F' ,'G' ,'H' ,'I' ,'J' ,'K' ,'L' ,'M' ,'N' ,'O','P' ,'Q' ,'R' ,'S' ,'T' ,'U' ,'V' ,'W' ,'X' ,'Y','Z' };
char Lowercase[26] = { 'a','b','c' ,'d' ,'e' ,'f' ,'g' ,'h' ,'i' ,'j' ,'k' ,'l' ,'m' ,'n' ,'o','p' ,'q' ,'r' ,'s' ,'t' ,'u' ,'v' ,'w' ,'x' ,'y','z' };
for (int i = 0; i < password.length(); i++) {
for (int k = 0; k < 26; k++) {
int add = (shift + k)%26;
if (password[i] == Uppercase[k]) {
password[i] = Uppercase[add]; // converting each letter
break;
}
else if (password[i] == Lowercase[k]) {
password[i] = Lowercase[add]; //converting each letter
break;
}
}
}
return password;
}
int main() {
cout << "Please enter an integer different from 0 and multiples of 25: ";
string password = "Abc def ghi 999 -*%/&()[]";
int shift;
cin >> shift;
cout<< Cipher(password, shift);
system("pause>0");
}

最新更新