Шифр Виньера в C: пробел не игнорируется

Общее объяснение шифра Виньера:

Шифр Виньера — это метод шифрования, аналогичный шифру Цезаря. Этот шифр принимает слово в качестве аргумента и интерпретирует алфавит слова следующим образом: a как 0, b как 1, c как 2 и так далее.

Таким образом, если ваш входной ключ «abc» и вы хотите, чтобы что-то вроде «привет привет» было зашифровано, вывод будет означать, что h останется прежним, i сдвинется на 1 место, h сдвинется на 2 места, e снова останется тем же (как он сдвигается на 0), l сдвигается на 1 позицию, другая l — на 2 и т. д. и т. д.

Основная идея состоит в том, что каждая буква смещается на соответствующую букву в аргументе, а пробелы и другие знаки препинания игнорируются. Если аргумент короче сообщения (как это бывает в большинстве случаев), аргумент просто зацикливается вокруг сообщения.


Моя проблема:

Единственная проблема, которая сохраняется, заключается в том, что он, кажется, делает правильную вещь для первого слова предложения. Это не игнорирование пробелов.

Я вставил свой новый код ниже.

Например, для программы ./vigenere bacon и сообщения Meet me at the park at eleven am я бы ожидал Negh zf av huf pcfx bt gzrwep oz в качестве вывода. Однако я получаю Negh ne og tjs qaty bt svfvgb bm. Или, например, когда я запускаю программу ./vignere bc на ABCD ABCD, я бы ожидал BDDF BDDF. Вместо этого я получаю BDDF CCEE (вывод, когда он применяет что-то вроде bcbcbcbcb, а не bcbc bcbc.

В то время как первое слово изменяется правильно, кажется, что оно шифрует все предложение, тогда как оно должно просто шифровать алфавиты — я указал это с помощью команды isalpha.

Вот почему это кажется немного загадочным.

КОД:

# include <cs50.h> 
# include <stdio.h> 
# include <stdlib.h>
# include <string.h>
# include <ctype.h>

int main(int argc, string argv[])

{
    string word = argv[1];
    int i = 0;
    int j = 0;


    if (argc != 2 || isalpha(word[j]) == false)
    {
        printf("Please enter a valid command line argument! \n");
        return 1;
    }

    else if (isalpha(word[j]))
    {
        printf("Message: "); 
        string message = GetString();

        for (int n = strlen(message); i < n; i++)
        {
               int plaintext = message[i];
               int ciphertext = word[j]; 
               int uppcb = (plaintext - 65 + ciphertext - 65);
               int upcipher1 = (uppcb) % 26;
               int uplc = (plaintext - 65 + ciphertext - 97);
               int upcipher2 = (uplc) % 26;
               int lopcb = (plaintext - 97 + ciphertext - 97);
               int locipher1 = (lopcb) % 26;
               int lolp = (plaintext - 97 + ciphertext - 65);
               int locipher2 = (lolp) % 26;

               if (isupper(word[j]) && isupper(message[i])) 
                {
                    j = (j+1)%strlen(word);
                    int upcode = (upcipher1 + 65); 
                    printf("%c", upcode);
                }

                else if (isupper(message[i]) && islower(word[j]))
                {
                    j = (j+1)%strlen(word);
                    int upcode1 = (upcipher2 + 65);
                    printf("%c", upcode1);
                }

                else if (islower(message[i]) && islower(word[j]))
                {
                    j = (j+1)%strlen(word);
                    int locode = (locipher1 + 97); 
                    printf("%c", locode);
                }

                else if (islower(message[i]) && isupper(word[j]))
                {
                    j = (j+1)%strlen(word);
                    int locode1 = (locipher2 +97);
                    printf("%c", locode1);
                }

                else 
                {
                    printf("%c", message[i]);
                }          

        }
        printf("\n");     
    }


}

ПРИМЕЧАНИЕ. На самом деле это C, а не C++, и некоторые команды, такие как GetInt() и GetString(), доступны в библиотеке CS50, которую я использую.


person boametaphysica    schedule 06.06.2014    source источник


Ответы (1)


Вам нужна еще одна индексная переменная для переменной word, например j, поскольку word и message — это две разные переменные, которые могут иметь разную длину.

Таким образом, вместо if (isupper(word[i]) && isupper(message[i])) у вас будет что-то вроде if (isupper(word[j]) && isupper(message[i])), в котором индексная переменная j считает от нуля до strlen(word) - 1, а затем начинает с нуля.

Причина, по которой это работает для вашего особого случая, заключается в том, что message и word имеют одинаковую длину, поэтому нет необходимости снова перезапускать индекс word с нуля, когда достигается конец строки в word.

person Richard Chambers    schedule 06.06.2014
comment
@boametaphysica, пожалуйста, обновите ваш вопрос, исходный пример и примеры вывода вашей последней версией. Удалите старую версию и установите новую версию. - person Richard Chambers; 07.06.2014
comment
Спасибо, я обновил свой код, свой вывод и новую проблему, с которой столкнулся. - person boametaphysica; 07.06.2014
comment
Я получил спасибо! :) - person boametaphysica; 07.06.2014