2

So, I am writing an encryption code. My code takes the word or any message and also asks user to enter a key. The end output is the encrypted message. For example:

Please enter the text you want to encrypt: hello
Enter the key: 4
The encrypted text is: lipps

But there is a problem. When I enter text that contains an s inside, it gives a question mark for the encryption:

Please enter the text you want to encrypt: ssss
Enter the key: 13
The encrypted text is: ����

This problem doesn't occur when I write other keys than 13, and if the letter is uppercase. This problem happens when the text contains any letter that comes after s (t, v, u, w, x, y, z) and when the key is 13.

Aforementioned code is:

#include <stdio.h>
#include <string.h>
    
int main(void) {
    int i;
    int key;
    char text[101], ch;
    printf("Please enter the text you want to encrypt: ");
    fgets(text, sizeof(text), stdin);
    printf("Enter the key: ");
    scanf("%i", &key);
    for(i = 0; text[i] != '\0'; ++i){
        ch = text[i];
            
        if(ch >= 'a' && ch <= 'z'){
            ch = ch + key;
                
            if(ch > 'z'){
                ch = ch - 'z' + 'a' - 1;
            }
                
            text[i] = ch;
        }
        else if(ch >= 'A' && ch <= 'Z'){
            ch = ch + key;
                
            if(ch > 'Z'){
                ch = ch - 'Z' + 'A' - 1;
            }
                
            text[i] = ch;
        }
    }
    printf("The encrypted text is: %s", text);
}
Adrian Mole
  • 49,934
  • 160
  • 51
  • 83

1 Answers1

2

The problem lies in the line ch = ch + key; when you have values for ch and key whose sum is greater than that which can be stored in a char variable. For example, for the character, 's' (ASCII value 115) and a key of 13, the sum is 128 - which overflows an 8-bit signed char (max value 127) and results in a negative number.

The problem is much less likely to occur for uppercase characters (unless you have a very big value for key), as their ASCII values are significantly lower ('A' thru 'Z' are 65 … 90, whereas 'a' thru 'z' are 97 … 122).

To fix the issue, make the 'temporary' ch variable an int and cast it back to a char after all calculations are complete:

#include <stdio.h>
#include <string.h>

int main(void)
{
    int i, ch; // Use an int for our temporary "ch" variable
    int key;
    char text[101];
    printf("Please enter the text you want to encrypt: ");
    fgets(text, sizeof(text), stdin);
    printf("Enter the key: ");
    scanf("%i", &key);
    for (i = 0; text[i] != '\0'; ++i) {
        ch = text[i];
        if (ch >= 'a' && ch <= 'z') {
            ch = ch + key;
            if (ch > 'z') {
                ch = ch - 'z' + 'a' - 1;
            }
            text[i] = (char)ch; // Cast the int to a char to avoid compiler warnings
        }
        else if (ch >= 'A' && ch <= 'Z') {
            ch = ch + key;

            if (ch > 'Z') {
                ch = ch - 'Z' + 'A' - 1;
            }
            text[i] = (char)ch;
        }
    }
    printf("The encrypted text is: %s", text);
    return 0;
}
Adrian Mole
  • 49,934
  • 160
  • 51
  • 83