Общее объяснение шифра Виньера:
Шифр Виньера — это метод шифрования, аналогичный шифру Цезаря. Этот шифр принимает слово в качестве аргумента и интерпретирует алфавит слова следующим образом: 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, которую я использую.