首页 > 解决方案 > 49 + 82 = -190?c++ 凯撒移位

问题描述

我正在研究加密消息的代码。首先,我像这样应用Ceasar shift:

message[i] += offset;

在 i = 40 的情况下,偏移量等于 49,message[40] 等于 82。所以 82 += 49 应该是 131。(我记录了之前和之后的每个值)而不是 131,message[40] 现在是 -190 .

这是整个代码:

string encode(vector<string> rotors, string message, int offset)
{
    for (int i = 0; i < message.length(); i++)
    {
        message[i] += offset; // ceasar shift
        while (message[i] > 'Z') message[i] -= 26; // in case the value of the letter is larger than Z go back to the beginning of the alphabet

        for (int j = 0; j < rotors.size(); j++) // the other part of enigma encryption
        {
            message[i] = rotors[j][message[i] - 65];
        }
        offset++; // increase ceasar shift
    }
    return message;
}

转子是一个随机字母向量,消息是一个不超过 50 个字符的字符串,并偏移一个整数以用于 ceasar 移位(如果这很重要)。

所以我的问题是:为什么它会在 82 + 49 中得到 -190?这不仅发生在我的 PC 上,也发生在在线编译器上。

编辑:这只适用于 i = 40 和 offset = 49 的特殊情况。在所有其他情况下(更大或更小),它按预期工作。

如果你想重现这个:

#include <iostream>
#include <string>
#include <vector>
#include <algorithm>

using namespace std;

string encode(vector<string> rotors, string message, int offset) {
    for (int i = 0; i < message.length(); i++) {
        message[i] += offset;
        while (message[i] > 'Z') message[i] -= 26;
        for (int j = 0; j < rotors.size(); j++) {
            message[i] = rotors[j][message[i] - 65];
        }
        offset++;
    }
    return message;
}

int main()
{
    string message;
    int pseudoRandomNumber;
    vector<string> rotors;
    cin >> pseudoRandomNumber; cin.ignore();

    for (int i = 0; i < 3; i++) {
        string rotor;
        getline(cin, rotor);
        rotors.push_back(rotor);
    }
    getline(cin, message);

    message = decode(rotors, message, pseudoRandomNumber);

    cout << message << endl;
}

复制它并将其作为输入:

9
BDFHJLCPRTXVZNYEIWGAKMUSQO
AJDKSIRUXBLHWTMCQGZNPYFVOE
EKMFLGDQVZNTOWYHXUSPAIBRCJ
EVERYONEISWELCOMEHEREEVERYONEISWELCOMEHERE

标签: c++charvariable-assignmentcalculation

解决方案


如果该类型char表现为 signed char 类型,则可以通过以下方式获得可以存储在该类型对象中的最小值和最大值

#include <iostream>
#include <limits>

int main() 
{
    std::cout << static_cast<int>( std::numeric_limits<char>::min() ) << '\n';
    std::cout << static_cast<int>( std::numeric_limits<char>::max() ) << '\n';

    return 0;
}

程序输出为

-128
127

那就是一个对象的类型char是无法存储值的131

如果以131十六进制输出值

#include <iostream>
#include <iomanip>

int main() 
{
    std::cout << std::hex << std::showbase << 131 << '\n';
    
    return 0;
}

那么你会得到

0x83

二进制看起来像

10000011

正如所见,符号位已设置

10000011`
^

所以存储在类型对象中的这个值char代表一个负数。


推荐阅读