Печать Caesar Shift на C печатает введенный текст HELLO - PullRequest
0 голосов
/ 22 декабря 2018

Я пытаюсь выполнить шифр Цезаря из текста от пользователя, используя операцию по модулю с символами ascii.Но мой код просто печатает введенный тест.Например, когда введенный текст - HELLO, программа возвращает «HELLO».Цель состоит в том, что для ключа 13 должно быть напечатано URYYB.Спасибо.

#include <cs50.h>
#include <stdio.h>
#include <string.h>
#include <ctype.h>
#include <stdlib.h>
int key = atoi(argv[1]);

string plaintext = get_string("Enter plaintext: ");

for (int i = 0; i < strlen(plaintext); i++)
{
    if (isalpha(plaintext[i]))
    {
        if (isupper(plaintext[i]))
        {
            printf("%c", ((plaintext[i] + key) % 26) + 65);
        }
        else if (islower(plaintext[i]))
        {
            printf("%c", ((plaintext[i] + key) % 26) + 97);
        }
        else
        {
            printf("%c", plaintext[i]);
        }
    }
}
printf("\n");

Ответы [ 3 ]

0 голосов
/ 22 декабря 2018

Предварительный анализ

Код символа 'H' равен 72.

(72 + 13)% 26 + 65 = 85% 26 + 65 = 7 + 65 ~ 'H'

Давайте посмотрим, будем ли мы сначала вычитать 65:

(72 - 65 + 13)% 26 + 65 = (7 + 13)% 26 + 65 = 20% 26 + 65 = 20 + 65= 85 ~ 'U'

Решение

printf("%c", ((plaintext[i] + key - 65) % 26) + 65);

и

printf("%c", ((plaintext[i] + key - 97) % 26) + 97);

соответственно.

Доказательство

Если у вас естькод символа, C, где S <= C <S + 26, тогда вы использовали следующую формулу: </p>

((клавиша C +)% 26) + S

, однако фактическаябуква L, и мы знаем, что

C = S + L,

, поэтому формула

((S + L + клавиша)% 26) + S

и, поскольку

(A + B)% C = ((A% C) + (B% C))% C,

с заменой A на (S),B с (L + клавиша) и C с 26, мы получаем:

((S% 26) + ((L + клавиша)% 26))% 26, мы видим, что результат искажается на (S% 26), что в случае 65 равно 13. Поскольку искажение 13 + ключ 13 вы использовали в модуле clзадница из 26 даст начальную букву!

Итак, предложенная новая формула

((C + key - S)% 26) + S = (((S + L) +клавиша - S)% 26) + S = ((L + клавиша)% 26) + S

- это именно то, что вам нужно.

0 голосов
/ 22 декабря 2018

Вы добавляете key к значению каждого символа открытого текста, когда оно предназначено для применения к соответствующему индексу буквы в алфавите.Например, в случае 'H' в ASCII ваша формула будет иметь вид: (72 + 13) % 26, который дает 7 (который также является индексом H в алфавите, начиная с нуля).

Youнеобходимо преобразовать (ASCII) значение символа в его индекс перед применением ключа, например, ((plaintext[i] - 'A' + key) % (1 + 'Z' - 'A')) + 'A'.

. Тогда решение для 'H' станет (72 - 65 + 13) % 26, что дает 20 (правильный ответ, 7 + 13, индекс U).

0 голосов
/ 22 декабря 2018

Ваша функция шифрования ничего не делает, если ключ 13:

, запустите немного исправленный и посмотрите результат: D

int main()
{
    int key = 13;

    char  plaintext[] = "HELLO";

    for (int i = 0; i < strlen(plaintext); i++)
    {
        if (isalpha(plaintext[i]))
        {
            if (isupper(plaintext[i]))
            {
                printf("%d, %d\n", (int)plaintext[i], (int)(((plaintext[i] + key) % 26) + 65));
            }
            else 
            {
                if (islower(plaintext[i]))
                {
                    //printf("%c", ((plaintext[i] + key) % 26) + 97);
                }
                else
                {
                    //printf("%c", plaintext[i]);
                }
            }
        }
    }
    printf("\n");
    return 0;
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...