Почему программа неправильно шифрует текст по Виженеру. Си

Что у меня в коде не так? Вместо правильно зашифрованного текста, какой-то бред: например, ключ stack кодирует слово overflow с выходом текста +0EN21. В чем у меня проблема? Я уже несколько дней не могу написать этого е**ного Виженера

#include <stdio.h>
#include <math.h>
#include <string.h>
int main()
{
char a[1000];
char b[1000];
int c;
int d;
int i;
i=0;
printf("Введіть текст ");
fgets(a,1000,stdin);
printf("Введіть ключ ");
fgets(b,1000,stdin);
c=strlen(a);
d=strlen(b);
for (i=0;i<=c;i++) {if (i%d==0) {a[i]=a[i]+(65-b[i]); if (a[i]>90) {a[i]=64+(a[i]-90);}}}
for (i=0;i<=c;i++) {if (i%d!=0) {a[i]=a[i]+(65-b[i%d]); if (a[i]>90) {a[i]=64+(a[i]-90);}}}
for (i=0;i<=c;i++) {if (i%d==0) {a[i]=a[i]+(97-b[i]); if (a[i]>122) {a[i]=96+(a[i]-122);}}}
for (i=0;i<=c;i++) {if (i%d!=0) {a[i]=a[i]+(97-b[i%d]); if (a[i]>122) {a[i]=96+(a[i]-122);}}}
printf("%s",a);
}

Ответы (1 шт):

Автор решения: DmitryK

Ну вы сами запутались в магических числах и циклах. И циклы у вас почему-то не i<c, а i<=c.

for( i=0; i<=c; i++) // i<=c - неправильно

Также незачем разделять ситуации if (i%d==0) - просто используете b[i%d]

// вместо вот этого
for(i=0;i<=c;i++) 
    if(i%d==0) 
        {a[i]=a[i]+(65-b[i]);}
for(i=0;i<=c;i++) 
    if(i%d!=0) 
        {a[i]=a[i]+(65-b[i%d]);}

// просто используете
for(i=0;i<c;i++) 
    a[i]=a[i]+(65-b[i%d]);

Всего 2 формулы можно взять из статьи на википедии шифр Вижинера
тогда шифрование выглядит так

for (i=0; i<c; i++)
    a[i] = (a[i] - 'A' + b[i%d] - 'A') % 26 + 'A'; // 26 - количество букв в алфавите

а дешифрование так

for (i=0; i<c; i++) 
{
    a[i] = a[i] - b[i%d];
    if(a[i] < 0)
        a[i] += 26; 
    a[i] += 'A';
}

И не забывайте, что это работает только для заглавных букв латинского алфавита. Т.е. вам нужно либо проверять входные данные на то, что это заглавные буквы, либо приводить их к верхнему регистру. Точнее - работать будет, но английские заглавные буквы будут дешифроваться правильно, а все остальные символы - неправильно.
Ещё можете взять базу не 26 - от A до Z, а 58 - от A до z. Тогда правильно будут шифроваться/дешифроваться все символы, лежащие в таблице символов от заглавной A до прописной z.

→ Ссылка