【发布时间】:2021-08-19 00:53:26
【问题描述】:
我正在研究加密消息的代码。首先,我像这样应用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;
}
rotors 是一个由随机字母组成的向量,消息是一个不超过 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
【问题讨论】:
-
“特殊情况”表示您有内存损坏/未定义行为/nasal demons。您能否展示一个minimal reproducible example,其他人都可以完全如图所示剪切/粘贴、编译、运行和重现您的结果?
-
有符号算术溢出,导致未定义行为。如果普通
char有符号或无符号,则定义它的实现。在你的情况下,它似乎是一个签名类型。 -
std::string使用char元素。char没有附加明确的signed或unsigned将是 有符号或无符号,具体取决于编译器实现。在您的情况下,char已明确签名,这意味着它的有效范围为-128..127,而131超出该范围,因此您遇到整数溢出。 -
请注意,即使您使所有字符都明确无符号(包括字符串中的字符),如果这是您的目标,您仍然会遇到结果可能无法打印的问题。
-
是
message[40]-190 还是 -125(存储为 8 位二进制补码有符号数时为 82 + 49),其中 -190 来自 -125 - 65(提升后message[i]在减法之前从 char 到 int)?
标签: c++ char variable-assignment calculation