c++ - Caesar Cipher 无法在 C++ 中正确解密的问题
问题描述
我知道这个问题已经被问过几次,我可能错过了回答我的具体问题的问题,但是我似乎找不到一个能给我一个适合我的答案的问题。
当我解密凯撒密码时,它似乎没有正确环绕,我的代码似乎遵循凯撒密码的特定数学,但它似乎在应该环绕时返回垃圾输出。我的代码如下,包括我用来测试问题的系统。
#include "main.h"
#include <QCoreApplication>
#include <QDebug>
String caesarCipher(QString in, int shift, bool decrypt)
/*
* Caesar shift is mathmatically represented as e = (q + s) mod 26
* Decryption is represented as d = (q - s) mod 26
* ROT13 is a caesar shift with 13 shift
*/
{
QString out;
if (!decrypt)
{
for (int i = 0; i < in.length(); ++i)
{
if (in[i] >= 'a' && in[i] <= 'z')
{
int q = (in[i].unicode() - 'a');
int e = (q + shift) % 26;
out += e + 'a';
}
else if (in[i] >= 'A' && in[i] <= 'Z')
{
int q = (in[i].unicode() - 'A');
int e = (q + shift) % 26;
out += e + 'A';
}
else
out += in[i];
}
return out;
}
else
{
for (int i = 0; i < in.length(); ++i)
{
if (in[i] >= 'a' && in[i] <= 'z')
{
int q = (in[i].unicode() - 'a');
int d = (q - shift) % 26;
int r = d + 'a';
out += r;
}
else if (in[i] >= 'A' && in[i] <= 'Z')
{
int q = (in[i].unicode() - 'A');
int d = (q - shift) % 26;
int r = d + 'A';
out += r;
}
else
out += in[i];
}
return out;
}
}
int main() // Testing
{
QString testString = "abcdefghijklmnopqrstuvwxyz";
QString upperTest = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
const int shifting = 3;
qDebug() << "Test String: " << testString;
qDebug() << "Test String (Upper): " << upperTest;
{
QString e = caesarCipher(testString, shifting, false);
QString E = caesarCipher(upperTest, shifting, false);
QString d = caesarCipher(e, shifting, true);
QString D = caesarCipher(E, shifting, true);
qDebug() << "Shift amount: " << shifting;
qDebug() << "Encrypt (Lower): " << e;
qDebug() << "Encrypt (Upper): " << E;
qDebug() << "Decrypt (Lower): " << d;
qDebug() << "Decrypt (Upper): " << D;
}
return 0;
}
预期的结果是
Test String: "abcdefghijklmnopqrstuvwxyz"
Test String (Upper): "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
Shift amount: 3
Encrypt (Lower): "defghijklmnopqrstuvwxyzabc"
Encrypt (Upper): "DEFGHIJKLMNOPQRSTUVWXYZABC"
Decrypt (Lower): "abcdefghijklmnopqrstuvwxyz"
Decrypt (Upper): "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
Press <RETURN> to close this window...
我得到的结果:
Test String: "abcdefghijklmnopqrstuvwxyz"
Test String (Upper): "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
Shift amount: 3
Encrypt (Lower): "defghijklmnopqrstuvwxyzabc"
Encrypt (Upper): "DEFGHIJKLMNOPQRSTUVWXYZABC"
Decrypt (Lower): "abcdefghijklmnopqrstuvw^_`"
Decrypt (Upper): "ABCDEFGHIJKLMNOPQRSTUVW>?@"
Press <RETURN> to close this window...
我试图移动代码,更改删除移位的位置,完成模数的位置以及添加“a”字符的位置
作为参考,代码最初是在我为了可读性而改变它之前:
for (int i = 0; i < in.length(); ++i)
{
if (in[i] >= 'a' && in[i] <= 'z')
out.resultString += (((in[i].unicode() - 'a') - shift) % m) + 'a';
else if (in[i] >= 'A' && in[i] <= 'Z')
out.resultString += (((in[i].unicode() - 'A') - shift) % m) + 'A';
else
out.resultString += in[i];
}
解决方案
与负数一起使用时,%
运算符可以返回负数。在您的情况下,解密“a”时,q
将为0,d
将是(-3 % 26),可以是-3。
解决方案是在计算余数之前确保数字是正数:
int d = (q - shift + 26) % 26;
或者,如果移位量未知,或者可能超过 25,请检查是否d
为负数,并在初始计算后将 26 添加到它。