C ++ Цезарь Cipher - понимание ключей ASCII

0

В настоящее время я делаю программу шифрования цезаря. Он должен шифроваться как в нижнем, так и в верхнем регистре.

например, если я набрал 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' вместо '>'

Мои понятия могут быть неправильными, поэтому мне нужна помощь.

  • 2
    48% 26 на самом деле 22.
  • 0
    Если вы просто хотите сдвинуть символы вправо на 3, зачем все лишние операции. Можете ли вы объяснить, почему бы просто не добавить 3?
Показать ещё 6 комментариев
Теги:

1 ответ

0

Позвольте мне связать диаграмму ASCII, которую я использую сначала: http://pl.wikipedia.org/wiki/ASCII. Веб-сайт польский, но таблица сама по-английски.

Я думаю, что очевидно, что проблема - это эквация, которую вы используете:

(((letter-52)+3) % 26) + 52;

Фактически первая буква в ASCII равна 65 (шестнадцатеричная 0x41 - следовать приведенной диаграмме). Ваша идея с модулем была бы прекрасной, если бы не было символов между буквенными блоками в ASCII. Но есть (еще раз проверить график).

Вот почему вы должны вручную проверить, есть ли знак:

  1. является заглавной буквой: if (letter >= 0x41 && letter <= 0x5a)
  2. не является капиталом: if (letter >= 0x61 && letter <= 0x7a)

Обычно при создании шифров Ceasar вы должны следовать этим:

  1. Замените заглавную букву с заглавной буквой, перемещенной в алфавите на заданный номер.
  2. Если письмо будет отсутствовать в области алфавита, продолжите итерацию с начала алфавита (X сдвинулся 5 вправо, давал бы C).
  3. Другие символы остаются такими же

Теперь давайте реализовать это (в коде я буду использовать буквенные значения символов - чтобы избежать ошибок):

#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");
}
  • 0
    Ваш код находится на правильном пути. Однако обратите внимание, что 'Z' - 'A' - это 25, а не 26. Честно говоря, я думаю, что было бы так же ясно использовать 26, как 'Z' - 'A' + 1 . Также было бы разумно использовать isupper() и islower() для идентификации букв каждого случая, хотя сравнение диапазонов работает с ASCII. Я также написал бы код, чтобы избежать использования continue : возможно, используйте char c; и назначить его в трех вариантах цепочки if / else if / else а затем завершить тело цикла result += c; ,

Ещё вопросы

Сообщество Overcoder
Наверх
Меню