Шифр Цезаря — это вид шифра подстановки, в котором каждый символ в открытом тексте заменяется символом, находящимся на некотором постоянном числе позиций левее или правее него в алфавите. Если в алфавите меньше букв, чем получившийся номер буквы, то отсчет ведется с начала алфавита.
Если мы будем зашифровывать слово kenig
используя сдвиг размером 13, то получим xravt
.
Ваша задача состоит в том, что бы расшифровать строку.
Вам дана зашифрованная строка, состоящая не более чем из 1000 строчных или заглавных букв латинского алфавита.
Далее записан размер сдвига k
, с помощью которого было зашифровано сообщение (0<=k<=10^9).
Выведете исходную строку.
Примеры ввода и вывода:
xravt 13
=> kenig
.
furg 3
=> crod
.
ZaQzJzCzAqZ 51
=> AbRaKaDaBrA
.
Во-первых, заметим, что в латинском алфавите 26 букв.
Далее, вместо сдвига k
можно рассматривать его остаток от деления на 26 (так как если k
>= 26, то всё равно всё будет сдвигаться по циклу).
Из второго примера следует, что k
обозначает сдвиг вправо. Поэтому для расшифровки нам надо будет сдвигать буквы влево.
Отдельно надо разобраться со строчными и заглавными буквами: при сдвиге строчных должны получаться строчные, а при сдвиге заглавных - заглавные. Нам достаточно знать, что в таблице ASCII и строчные и заглавные буквы идут подряд по алфавиту.
#include <iostream>
#include <string>
using namespace std;
int main() {
const int alphabet_size = 26;
string word;
cin >> word;
unsigned int shift;
cin >> shift;
shift %= alphabet_size;
for (size_t i = 0; i != word.size(); ++i) {
bool upper = isupper(word[i]);
word[i] = word[i] - shift;
if (upper) {
if (word[i] < 'A') {
word[i] += alphabet_size;
}
} else {
if (word[i] < 'a') {
word[i] += alphabet_size;
}
}
}
cout << word << "\n";
}
Вместо вложенных if
можно было бы использовать формулу для индексов с остатками от деления на alphabet_size
.