В настоящее время я делаю программу шифрования цезаря. Он должен шифроваться как в нижнем, так и в верхнем регистре.
например, если я набрал a, он затем сдвинет ключи на 3, а конечный результат станет d.
Взгляните на мои коды
char c;
c = (((97-52)+3) % 26) + 52;
cout << c;
Буква "a" имеет код ASCII 97.
Итак, по праву
1) ((97-52)+3) will give you 48
2) 48 % 26 will give you 8 since 48/26 will give you a remainder of 8.
3) 8 + 52 = 60(which will by right give you a value of '>' according to the ascii table)
но мой результат, который у меня есть, - это J, и я не понимаю, откуда я получаю вывод 'J' вместо '>'
Мои понятия могут быть неправильными, поэтому мне нужна помощь.
Позвольте мне связать диаграмму ASCII, которую я использую сначала: http://pl.wikipedia.org/wiki/ASCII. Веб-сайт польский, но таблица сама по-английски.
Я думаю, что очевидно, что проблема - это эквация, которую вы используете:
(((letter-52)+3) % 26) + 52;
Фактически первая буква в ASCII равна 65
(шестнадцатеричная 0x41
- следовать приведенной диаграмме). Ваша идея с модулем была бы прекрасной, если бы не было символов между буквенными блоками в ASCII. Но есть (еще раз проверить график).
Вот почему вы должны вручную проверить, есть ли знак:
if (letter >= 0x41 && letter <= 0x5a)
if (letter >= 0x61 && letter <= 0x7a)
Обычно при создании шифров Ceasar вы должны следовать этим:
Теперь давайте реализовать это (в коде я буду использовать буквенные значения символов - чтобы избежать ошибок):
#include <iostream>
#include <cstdlib>
using namespace std;
string Ceasar(string input, int offset)
{
string result = "";
for (int i = 0; i < input.length(); ++i)
{
// For capital letters
if (input[i] >= 'A' && input[i] <= 'Z')
{
result += (char) (input[i] - 'A' + offset) % ('Z' - 'A') + 'A';
continue;
}
// For non-capital
if (input[i] >= 'a' && input[i] <= 'z')
{
result += (char) (input[i] - 'a' + offset) % ('z' - 'a') + 'a';
continue;
}
// For others
result += input[i];
}
return result;
}
int main()
{
cout << Ceasar(string("This is EXamPLE teXt!?"), 8).c_str();
system("PAUSE");
}
'Z' - 'A'
- это 25, а не 26. Честно говоря, я думаю, что было бы так же ясно использовать 26, как 'Z' - 'A' + 1
. Также было бы разумно использовать isupper()
и islower()
для идентификации букв каждого случая, хотя сравнение диапазонов работает с ASCII. Я также написал бы код, чтобы избежать использования continue
: возможно, используйте char c;
и назначить его в трех вариантах цепочки if / else if / else
а затем завершить тело цикла result += c;
,