首页 > 解决方案 > 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];
}

标签: c++caesar-cipher

解决方案


与负数一起使用时,%运算符可以返回负数。在您的情况下,解密“a”时,q将为0,d将是(-3 % 26),可以是-3。

解决方案是在计算余数之前确保数字是正数:

int d = (q - shift + 26) % 26;

或者,如果移位量未知,或者可能超过 25,请检查是否d为负数,并在初始计算后将 26 添加到它。


推荐阅读