Я должен написать код для случайной задачи шифрования. Я сделал это, но программа преобразует только прописные или строчные (в зависимости от того, что я выбираю) буквы в качестве входных данных. Что я должен изменить, чтобы программа преобразовывала как прописные, так и строчные буквы?
код:
srand(time(0)); //seed for rand()
static char alphabet[]="ABCDEFGHIJKLMNOPQRSTUVWXYZ";
string alph="ABCDEFGHIJKLMNOPQRSTUVWXYZ";
const int LENGTH=sizeof(alphabet)-1;
int r;
char temp;
for (unsigned int i=0; i<LENGTH; i++) //loop which shuffles the array
{
r=rand() % LENGTH;
temp=alphabet[i];
alphabet[i] = alphabet[r];
alphabet[r]=temp;
}
string text;
getline (cin, text);
for (unsigned int i=0; i<text.length(); i++) //loop to encrypt
{
if (isalpha(text[i]))
{
text[i]=alphabet[text[i] - 'A']; //index alphabet with the value of text[i], adjusted to be in the range 0-25
}
}
РЕДАКТИРОВАТЬ: Добавлен полный код (также для расшифровки этого шифра замены)
Добавьте второй алфавит строчных букв и измените его в том же цикле, который перемешивает массив первого алфавита, например:
temp=alphabet_of_lowerCase[i];
alphabet_of_lowerCase[i] = alphabet_of_lowerCase[r];
alphabet_of_lowerCase[r]=temp;
Теперь в вашей схеме шифрования просто проверьте, является ли символ строчными или заглавными буквами с islower
является isupper
функции и использовать необходимый алфавитный массив соответственно внутри isalpha
если ветка:
if (islower()) {
text[i]= alphabet_of_lowerCase[text[i] - 'a'];
}
else
// your previous code
Полный код:
static char alphabet[]="ABCDEFGHIJKLMNOPQRSTUVWXYZ";
static char text[] = "TEST";
void shuffleAlphabet() {
srand(time(0)); //seed for rand()
const int LENGTH = sizeof(alphabet)-1;
int r;
char temp;
for (unsigned int i=0; i<LENGTH; i++) //loop which shuffles the array
{
r=rand() % LENGTH;
temp=alphabet[i];
alphabet[i] = alphabet[r];
alphabet[r]=temp;
}
}
void cipher(int decrypt) {
for (unsigned int i=0; i<strlen(text); i++) //loop to encrypt
{
if (isalpha(text[i]))
{
if (!decrypt)
text[i]=alphabet[text[i] - 'A']; //index alphabet with the value of text[i], adjusted to be in the range 0-25
else {
int charPos = strchr(alphabet, text[i]) - alphabet; // calculate character position in cipher alphabet
text[i]='A' + charPos; // and advance forward in standard alphabet by this position
}
}
}
}
int main()
{
printf("Text: %s\n", text);
shuffleAlphabet();
printf("Cipher alphabet: %s\n", alphabet);
cipher(0);
printf("Encrypted: %s\n", text);
cipher(1);
printf("Decrypted: %s\n", text);
return 0;
}
Так что, в общем, вам нужно знать только алфавит шифрования, используемый для расшифровки зашифрованного текста. На самом деле вам даже не нужно знать алфавит шифрования
расшифровать зашифрованный текст, потому что вы можете использовать частотный анализ для взлома почти всех подстановочных шифров (включая шифрование XOR).
Если … ключ, используемый в подстановочном шифре, имеет ту же длину, что и размер исходного текста, и всегда случайный, — в этом случае мы получим неразрывный одноразовый блокнот.
Вы можете использовать std::transform()
Функция алгоритма с лямбда-выражением, которое возвращает преобразование символов верхнего или нижнего регистра.
#include <algorithm>
#include <cctype>
#include <string>
//...
std::string text;
//...
std::transform(text.begin(), text.end(), text.begin(), [](char c)
{ return isupper(c)?tolower(c):toupper(c); });
Живой пример: http://ideone.com/PJmc1b
std::transform
функция названа transform
по причине, и вышеупомянутый пример. Мы берем строку, перебираем ее и «трансформируем» каждый символ из нижнего в верхний (или наоборот). Лямбда-функция — это правило, применяемое к каждому символу в строке.