Я не могу понять, почему он говорит: «вывод не является допустимым текстом ASCII»!
Для того, чтобы вы поняли контекст проблемы, я опубликую то, что описано, чтобы сделать. ОНА НАЧИНАЕТСЯ ЗДЕСЬ!
В шифре замещения мы «зашифровываем» (то есть обратимым образом) сообщение, заменяя каждую букву другой буквой. Для этого мы используем ключ: в этом случае отображение каждой из букв алфавита на букву, которой она должна соответствовать, когда мы ее шифруем. Чтобы «расшифровать» сообщение, получатель сообщения должен знать ключ, чтобы он мог повернуть процесс вспять: перевести зашифрованный текст (обычно называемый шифротекстом) обратно в исходное сообщение (обычно называемое открытым текстом).
Ключом, например, может быть строка NQXPOMAFTRHLZGECYJIUWSKDVB
. Эта 26-символьная клавиша означает, что A
(первая буква алфавита) следует преобразовать в N
(первый символ клавиши), B
(вторая буква алфавита) следует преобразовать в Q
(второй символ ключа) и т. Д.
Сообщение, подобное HELLO
, будет затем зашифровано как FOLLE
, заменяя каждую из букв в соответствии с отображением, определенным key.
Давайте напишем программу под названием substitution, которая позволяет вам шифровать сообщения с использованием шифра замещения. Когда пользователь выполняет программу, он должен решить, предоставив аргумент командной строки, какой ключ должен быть в секретном сообщении, которое он предоставит во время выполнения.
Вот несколько примеров как программа может работать. Например, если пользователь вводит ключ YTNSHKVEFXRBAUQZCLWDMIPGJO
и открытый текст HELLO
:
$ ./substitution YTNSHKVEFXRBAUQZCLWDMIPGJO
plaintext: HELLO
ciphertext: EHBBQ
Вот как может работать программа, если пользователь предоставляет ключ VCHPRZGJNTLSKFBDQWAXEUYMOI
и открытый текст hello, world
:
$ ./substitution VCHPRZGJNTLSKFBDQWAXEUYMOI
plaintext: hello, world
ciphertext: jrssb, ybwsp
Обратите внимание, что ни запятая, ни пробел не были заменены шифром. Подставляйте только буквы алфавита! Также обратите внимание, что регистр исходного сообщения был сохранен. Строчные буквы остаются строчными, а прописные - прописными.
Не имеет значения, являются ли символы в самой клавише прописными или строчными. Ключ VCHPRZGJNTLSKFBDQWAXEUYMOI
функционально идентичен ключу vchprzgjntlskfbdqwaxeuymoi
(как, впрочем, VcHpRzGjNtLsKfBdQwAxEuYmOi
).
#include <cs50.h>
#include <stdio.h>
#include <string.h>
int main(int argc, string argv[])
{
if (argc != 2)
{
printf("Usage: ./substitution KEY");
return 1;
}
else if (argc == 2)
{
string text = argv[1];
string storing = text;
int counter = 0;
int i = 0;
bool number = true;
bool flag = true;
while (flag == true && i < 26)
{
if ((int)text[i] >= 48 && (int)text[i] <= 57)
{
number = false;
}
if (((int)text[i] >= 65 && (int)text[i] <= 90) || ((int)text[i] >= 97 && (int)text[i] <= 122))
{
counter++;
for ( int j = 0; j < counter - 1; j++)
{
if ((int)storing[j] == (int)text[i] || (int)storing[j] + 32 == (int)text[i])
{
flag = false;
}
}
}
i++;
}
if (number == false)
{
printf("Key must only contain alphabetic characters.");
return 1;
}
if (flag == false)
{
printf("Key must not contain repeated characters.");
return 1;
}
if (counter < 26)
{
printf("Key must contain 26 characters.");
return 1;
}
}
string plaintext = get_string("plaintext:");
string key = argv[1];
int counter;
bool not_letter;
bool capital1;
bool capital;
int crypto[strlen(plaintext)];
for (int i = 0; i < strlen(plaintext); i++)
{
capital1 = false;
capital = false;
not_letter = false;
if ((int)plaintext[i] >=65 && (int)plaintext[i] <= 90)
{
counter = (int)plaintext[i] - 65;
capital = true;
}
else if ((int)plaintext[i] >=97 && (int)plaintext[i] <= 122)
{
counter = (int)plaintext[i] - 97;
capital1 = true;
}
else
{
not_letter = true;
}
if (not_letter == true)
{
crypto[i] = (int)plaintext[i];
}
else if (capital == true)
{
if ((int)key[i] >=65 && (int)key[i] <= 90)
{
crypto[i] = (int)key[counter];
}
else if ((int)key[i] >=97 && (int)key[i] <= 122)
{
crypto[i] = (int)key[counter] - 32;
}
}
else if (capital1 == true)
{
if ((int)key[i] >=65 && (int)key[i] <= 90)
{
crypto[i] = (int)key[counter] + 32;
}
else if ((int)key[i] >=97 && (int)key[i] <= 122)
{
crypto[i] = (int)key[counter];
}
}
}
printf("ciphertext: ");
for (int i = 0; i < strlen(plaintext); i++)
{
printf("%c", (char)crypto[i]);
}
printf("\n");
return 0;
}
Когда я тестирую программу с check50 cs50/problems/2020/x/substitution
из CS50, она говорит:
:) substitution.c exists
:) substitution.c compiles
:) encrypts "A" as "Z" using ZYXWVUTSRQPONMLKJIHGFEDCBA as key
:) encrypts "a" as "z" using ZYXWVUTSRQPONMLKJIHGFEDCBA as key
:) encrypts "ABC" as "NJQ" using NJQSUYBRXMOPFTHZVAWCGILKED as key
:) encrypts "XyZ" as "KeD" using NJQSUYBRXMOPFTHZVAWCGILKED as key
:) encrypts "This is CS50" as "Cbah ah KH50" using YUKFRNLBAVMWZTEOGXHCIPJSQD as key
:) encrypts "This is CS50" as "Cbah ah KH50" using yukfrnlbavmwzteogxhcipjsqd as key
! :( encrypts "This is CS50" as "Cbah ah KH50" using YUKFRNLBAVMWZteogxhcipjsqd as key
output not valid ASCII text
! :( encrypts all alphabetic characters using DWUSXNPQKEGCZFJBTLYROHIAVM as key
output not valid ASCII text
:) handles lack of key
:) handles invalid key length
:) handles invalid characters in key
:) handles duplicate characters in key
:) handles multiple duplicate characters in key