Я написал программу на C, которая использует простой текст и пароль и создает шифрованный текст с использованием шифрования vigenere. Хотя код производит правильный вывод большую часть времени, я нашел пример, где он производит неожиданный вывод, и я не могу найти проблему самостоятельно. Выход, как, например:Шифр Vigenere в C
[email protected]:~/Desktop/programming/C/current/vigenere$ ./vigenere lemon attackatdawn
LXF OPV EFR NHR [0002]
Это поле в конце не появляется, как она должна, она предназначена для представления, когда Баш пытается отобразить ASCII символ 2, но копировать и вставлять не показывать это правильно , Это пример текста из Википедии для шифрования, и это единственный текст, который я нашел, который разбивает мою программу (я не знаю, в чем причина, поэтому я не могу ее реплицировать), но я уверен, что есть больше строк что приведет к аналогичным результатам. Я подозреваю, что сделал что-то, что порождает неопределенное поведение, но я не уверен. Что я тут сделал? Мой код:
// vigenere.c - Takes a plaintext and a cipher key from argv[1] and argv[2] and produces the cipher text according to Vigenere's cipher
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <ctype.h>
void string_clean(char *source) //Courtesy (mostly) of user 'Aaron' of StackOverflow
{
char *i = source;
char *j = source;
while(*j != 0) {
*i = *j++;
if(*i != ' ' && (isupper(*i) || islower(*i)))
i++;
}
*i = 0;
}
char *vigenere_enc(char plain[], char cipher[])
{
char *cipher_text;
string_clean(plain);
string_clean(cipher);
int plain_len = strlen(plain);
int cipher_len = strlen(cipher);
if(!(cipher_text = calloc(plain_len, sizeof(char))))
return 0;
for(int i = 0; i < cipher_len; i++) {
if(isupper(cipher[i]))
cipher[i] -= 'A';
else if(islower(cipher[i]))
cipher[i] -= 'a';
}
int j = 0;
for(int i = 0; i < plain_len; i++, j++) {
if(j == cipher_len)
j = 0;
if(isupper(plain[i]))
plain[i] -= 'A';
else if(islower(plain[i]))
plain[i] -= 'a';
cipher_text[i] = ((plain[i] + cipher[j]) % 26) + 'A';
}
return cipher_text;
}
int main(int argc, char *argv[])
{
if(argc != 3)
return 1;
char *cipher = vigenere_enc(argv[2], argv[1]);
for(int i = 0; i < strlen(cipher); i++) {
if(i % 3 == 0 && i != 0)
putchar(' ');
putchar(cipher[i]);
}
putchar('\n');
return 0;
}
Все и любая помощь/предложения больш оценены!
OP также пишет для входных строк в 'string_clean()', но аргументы, передаваемые в ' main() 'может не записываться. –
Большое спасибо за этот ответ, поскольку он решил мою проблему. Два вопроса, однако, зачем использовать malloc для calloc и почему plain_len + 1, а не plain_len? Не лучший день для офф- by-one.:/ –
'calloc' занумерует память, но вы все равно все равно не нуждаетесь в ней, но не нужно, чтобы она была равна нулю. И' + 1', потому что вам нужно место для упомянутого ограничителя строк. 'strlen()' does not включите это. –