2

I have made program which encrypts and decrypts Vigenere's cipher but I have several problems.

  • Here is one: First letter of sentence is encrypted incorrectly.
  • Second one: After sentence I have letter K. I think that's because of space but I don't know how to fix it.
  • And third problem: There are no spaces in encrypted sentence I know ages ago when Vigenere's cipher was used there were no spaces but I would like to have groups of 5 letters if that's possible.

Here's my code:

#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <string.h>
#include <ctype.h>

int main(int argc, char **argv) {
    char message[100];
    int choice;
    int i, j;
    char pass[33];
    int value;
    char repeat = 1;

    while (repeat == 1) {
        printf("Enter operation\n");
        printf("Encrypt - 1 \n");
        printf("Decrypt - 2\n");

        scanf("%d", &choice);

        if (choice == 1) {
            printf("Please enter message to encrypt\n");
            while (getchar() != '\n');
            fgets(message, 100, stdin);

            printf("Enter password\n");
            scanf("%s", &pass);

            for (i = 0, j = 0; i < strlen(message); i++, j++) {
                if (message[i] == ' ')
                    continue;

                if (j >= strlen(pass)) {  
                    j = 0;
                }
                if (!isupper(message[i])) {
                    value = (((message[i]) - 97) + ((pass[j]) - 97));
                }
                if (!islower(message[i])) {
                    value = (((message[i]) - 65) + ((pass[j]) - 65));   
                }
                printf("%c", 97 + (value % 26));
            }
            printf("\nWould you like to repeat? [1/0]\n");
            scanf("%d", &repeat);
        } else
        if (choice == 2) {
            printf("Enter message do decrypt\n");
            while (getchar() != '\n');
            fgets(message, 100, stdin);

            printf("Zadejte heslo\n");
            scanf("%s", &pass);

            for (i = 0, j = 0; i < strlen(message); i++, j++) {
                if (message[i] == ' ')
                    continue;

                if (j >= strlen(pass)) {  
                    j = 0;
                }
                if (!isupper(message[i])) {
                    value = (((message[i]) - 96) - ((pass[j]) - 96));
                }
                if (!islower(message[i])) {
                    value = (((message[i]) - 64) - ((pass[j]) - 64));   
                }
                if (value < 0) { 
                    value = value * -1; 
                }
                printf("%c", 97 + (value % 26));
            }
            printf("\nWould you like to repeat? [1/0]\n");
            scanf("%d", &repeat);
        }
    }
    return (EXIT_SUCCESS);
}

[And here's screen of output

popcorn
  • 43
  • 1
  • 5

2 Answers2

1

The main problem in your code is you apply the translation to characters with incorrect tests: you should translate uppercase letters is you have indeed an uppercase letter, not if you don't have a lowercase character. As coded, non letters are translated twice.

Change the code to:

            if (islower((unsigned char)message[i])) {
                value = (((message[i]) - 'a') + ((pass[j]) - 'a'));
            }
            if (isupper((unsigned char)message[i])) {
                value = (((message[i]) - 'A') + ((pass[j]) - 'a'));   
            }

Also make sure you use character constants instead of hard-coded ASCII values and make the password lowercase.

In the deciphering case, the offsets seem incorrect. You should be using 'A' and 'a' too.

chqrlie
  • 98,886
  • 10
  • 89
  • 149
  • Okay, i have fixed that, i'm gonna use characters instead of ASCII numbers. – popcorn Sep 20 '17 at 14:32
  • @popcorn: you are not supposed to *fix* the posted code in the question, because it makes the comments and answers inconsistent. You can add EDIT paragraphs with further explanations and extra questions. – chqrlie Sep 21 '17 at 19:16
0

First things first, the message corruption. If you add a few printf() statements in the loop that is doing the encryption, you should be able to get an idea what is going wrong. You can always comment them out, or remove them altogether, anytime later.

That K on the end could be the encrypted \n that would have been read in with the message.

To display the encrypted message in groups of five characters, keep a count of how many characters you have actually displayed (make sure the instruction to increase the count is located where it will get skipped if the character is not displayed); and when this reaches 5, display a space and reset the counter to zero.

bluerizlagirl
  • 21
  • 1
  • 3
  • I've added some printf's() and seems everything okay or? But i thought i will bump that K on the end with `while (getchar() != '\n');` – popcorn Sep 20 '17 at 14:39