gpt4 book ai didi

c++ - 仿射密码解密,大写和小写输出均不同

转载 作者:行者123 更新时间:2023-12-02 10:36:31 25 4
gpt4 key购买 nike

使用Affine密码解密纯文本时出现问题。
加密工作正常,但是将相同的逻辑应用于小写/大写字符的解密将返回不同的输出。

这是输出:

加密的消息是:ulctkbsjarizqhypgxofwnevmd ULCTKBSJARIZQHYPGXOFWNEVMD
解密后的消息是:opqrstuvwxyzabcdefghijklmn ABCDEFGHIJKLMNOPQRSTUVWXYZ

我怀疑这与ASCII值的获取有关,有人可以纠正我吗?

这是我的代码:

#include<bits/stdc++.h> 
using namespace std;

//Key values of a and b
const int a = 17;
const int b = 20;

string encryptMessage(string plainText)
{
string cipher = "";

for (int i = 0; i < plainText.length(); i++)
{
if(plainText[i]!=' ')
{
if ((plainText[i] >= 'a' && plainText[i] <= 'z') || (plainText[i] >= 'A' && plainText[i] <= 'Z'))
{
if (plainText[i] >= 'a' && plainText[i] <= 'z')
{
cipher = cipher + (char) ((((a * (plainText[i]-'a') ) + b) % 26) + 'a');
}

else if (plainText[i] >= 'A' && plainText[i] <= 'Z')
{
cipher = cipher + (char) ((((a * (plainText[i]-'A') ) + b) % 26) + 'A');
}

}
else
{
cipher += plainText[i];
}

}
else
{
cipher += plainText[i];
}

}
return cipher;
}

string decryptCipher(string cipher)
{
string plainText = "";
int aInverse = 0;
int flag = 0;

for (int i = 0; i < 26; i++)
{
flag = (a * i) % 26;

if (flag == 1)
{
aInverse = i;
}
}

for (int i = 0; i < cipher.length(); i++)
{
if(cipher[i] != ' ')
{
if ((cipher[i] >= 'a' && cipher[i] <= 'z') || (cipher[i] >= 'A' && cipher[i] <= 'Z'))
{
if (cipher[i] >= 'a' && cipher[i] <= 'z')
{
plainText = plainText + (char) ((((aInverse * (cipher[i]+ 'a') ) - b) % 26) + 'a');

}

else if (cipher[i] >= 'A' && cipher[i] <= 'Z')
{
plainText = plainText + (char) (((aInverse * ((cipher[i]+'A' - b)) % 26)) + 'A');

}

}
else
{
plainText += cipher[i];
}
}
else

plainText += cipher[i];
}

return plainText;

}

//Driver Program
int main(void)
{
string msg = "abcdefghijklmnopqrstuvwxyz ABCDEFGHIJKLMNOPQRSTUVWXYZ";

//Calling encryption function
string cipherText = encryptMessage(msg);
cout << "Encrypted Message is : " << cipherText<<endl;

//Calling Decryption function
cout << "Decrypted Message is: " << decryptCipher(cipherText);

return 0;
}


最佳答案

我已经考虑了一段时间,尽管我无法提供完整的解释,但是我有几个可能有用的“观察”,以及一个“作弊”解决方法。

首先,尽管您说“对小写/大写解密使用相同的逻辑”,但是每个解密块中代码的字符方式对齐显示这并非完全正确:

plainText = plainText + (char) ((((aInverse * (cipher[i]+ 'a') ) - b) % 26) + 'a'); // Lower case
plainText = plainText + (char) (((aInverse * ((cipher[i]+'A' - b)) % 26)) + 'A'); // Upper case

因此,将“小写”代码“固定”为与大写的(工作)代码完全相似(并删除多余的括号),这样做:

if (cipher[i] >= 'a' && cipher[i] <= 'z')
{
plainText = plainText + (char)( ( (aInverse * (cipher[i] + 'a' - b) ) % 26 ) + 'a' );
}
else if (cipher[i] >= 'A' && cipher[i] <= 'Z')
{
plainText = plainText + (char)( ( (aInverse * (cipher[i] + 'A' - b) ) % 26 ) + 'A' );
}

但是,这实际上并不能解决问题(只是稍作更改),因为输出如下:
Encrypted Message is : ulctkbsjarizqhypgxofwnevmd ULCTKBSJARIZQHYPGXOFWNEVMD
Decrypted Message is : qrstuvwxyzabcdefghijklmnop ABCDEFGHIJKLMNOPQRSTUVWXYZ

这里的问题是小写值都被 16值“旋转”了-看起来可疑地接近 a的值。另外,请注意,尽管加密公式中使用了 a,但解密中并未使用它。

因此,我想出了以下解决方法,假设(出于尚待推论的原因)在解码大写值时,此 16在ASCII值的位表示中以某种方式丢失了:

if ((cipher[i] >= 'a' && cipher[i] <= 'z') || (cipher[i] >= 'A' && cipher[i] <= 'Z'))
{
int offset = ((cipher[i] - 'A') / 26) ? a - 1 : 0;
if (cipher[i] >= 'a' && cipher[i] <= 'z') {
plainText = plainText + (char)( ( (aInverse * (cipher[i] + 'a' - b) - offset ) % 26 ) + 'a' );
}
else if (cipher[i] >= 'A' && cipher[i] <= 'Z') {
plainText = plainText + (char)( ( (aInverse * (cipher[i] + 'A' - b) - offset ) % 26 ) + 'A' );
}
}

请注意,可以使用标准库提供的功能并删除一些“冗余”检查来进一步简化/阐明您的代码:

for (int i = 0; i < cipher.length(); i++) {
if (isalpha(cipher[i])) {
int offset = islower(cipher[i]) ? a - 1 : 0;
int letter = islower(cipher[i]) ? 'a' : 'A';
plainText = plainText + (char)(((aInverse * (cipher[i] + letter - b) - offset) % 26) + letter);
}
else {
plainText += cipher[i];
}
}

关于c++ - 仿射密码解密,大写和小写输出均不同,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60039507/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com