Я написал этот код для проблемы Виженера в cs50. Однако это не работает должным образом, когда я печатаю зашифрованные буквы, я использую 58 и 90 вместо 65 и 97. (значения ASCII для A и a)
Это дает мне желаемый результат, но я не понимаю, почему это так. При вычитании на «а» или «А» я получаю неверный зашифрованный текст, что для меня не имеет никакого смысла.
Я поискал несколько разных решений, и все они вычитали с помощью «а» или «А», чтобы перейти к алфавитному указателю, однако это не работает для меня.
Я действительно не могу понять, почему я должен использовать эти значения в моем коде, возможно, кто-нибудь может помочь мне понять, что пошло не так или где моя логическая ошибка.
Заранее спасибо.
изменить: я изменил
k [z] = tolower (k [z]); to k [z] = toupper (k [z] - 'A');
и я также изменил
printf ("% c", (((p [j] - 58) + k [l% strlen (k)])% 26) + 'A'); для printf ("% c", (((p [j] - 'A' -6) + k [l% strlen (k)])% 26) + 'A');
-6 - это потому, что это дает мне правильный результат, означающий, что что-то все еще не работает
ключ: бекон
открытый текст: Встретимся в парке в одиннадцать утра
ожидаемый результат: Negh zf av huf pcfx bt gzrwep oz
фактический вывод с -6: Negh zf av huf pcfx bt gzrwep oz
фактический вывод без -6: Tkmn fl gb nal vild hz mfxckv uf
Почему-то все значения отклоняются на -6, и я не знаю почему.
Также k.size () дал мне ошибки, поэтому я оставил strlen ().
int main(int argc,string argv[])
{
//checks if only one argument was typed
if (argc != 2)
{
printf("Error");
return 1;
}
//assigns the keyword argv[1] to k
string k = argv[argc -1];
//check if key is alphabetical only
for (int i = 0 , n = strlen(k); i < n; i++)
{
if(!isalpha(k[i]))
{
printf("Key is not alphabetical");
return 1;
}
}
printf("Key Valid\n");
//convert key to lowercase only
for(int z = 0; k[z]; z++)
{
k[z] = tolower(k[z]);
}
string p = get_string("Plaintext: ");
//iterate over p
//l is incremented only when the char is alphabetical and is used as index for k
for (int j = 0,l = 0 , o = strlen(p);j < o ;j++)
{
if(isalpha(p[j]))
{
if(isupper(p[j]))
{
//print enciphered letter
printf("%c",(((p[j]- 58) + k[l % strlen(k)]) % 26) + 'A');
}
else if(islower(p[j]))
{
//print enciphered letter
printf("%c",(((p[j]- 90) + k[l % strlen(k)]) % 26 ) + 'a');
}
//increment so that next char in k is used
l++;
}
else
{
//print unchanged
printf("%c",p[j]);
}
}
return 0;
}
toupper
вместоtolower
? Заглавные буквы исторически используются по умолчанию (старый код FORTRAN был написан только заглавными буквами), поэтому буквы обычно нормализуются к верхнему регистру, а не к нижнему регистру. Но на самом деле ключ должен иметь значение 0 для буквы A, поэтому преобразование должно бытьtoupper(k[z]) - 'A'
, и после этого не должно быть задействовано никаких магических констант. - person Dialecticus   schedule 02.04.2018get_string
функция? Каков ваш вклад? Каков ваш ожидаемый результат? Каков ваш фактический результат? - person Retired Ninja   schedule 02.04.2018- 'A'
часть, тогда вы не можете использоватьstrlen(k)
и должны использоватьk.size()
, потому что нулевое значение может быть частью строки, аstrlen
считает нулевое значение символом конца строки, аstring::size()
- нет. - person Dialecticus   schedule 02.04.2018toupper(k[z] - 'A')
должно бытьtoupper(k[z]) - 'A'
. Но это означает, что если ключ имеет букву A и вы используетеstrlen
, код будет использовать только часть ключа перед буквой. Затем вы должны использоватьstring::size
и исследовать ошибку. Или, по крайней мере, введите новыйint k_length = strlen(k)
перед изменением содержимогоk
и используйтеk_length
вместоstrlen(k)
позже в коде. - person Dialecticus   schedule 02.04.2018strlen
функция считает байты от указанного указателя вперед, пока не найдет нулевой символ. С помощью части- 'A'
мы фактически превращаем предыдущийA
char в нулевой символ (который не то же самое, что'0'
char; более распространенное имя для этого нулевого символа - символ NUL). Вызовstrlen
для этого измененного указателяk
прекращается преждевременно. - person Dialecticus   schedule 03.04.2018