Search code examples
carrayscryptographycs50caesar-cipher

I am trying to perform a Caesar shift on the character z (ASCII 122). How do I give it "more room" to prevent it from overflowing past 127?


In the CS50 2019 Caesar assignment, I am supposed to perform Caesar shifts on characters by a given number of letters (key).

To do this, I add the value of key to each letter, as such:

for each character in plaintext:
    plaintext[character] += key

Since I want z to loop back to a, I then wrote:

while (ciphered_character > 122)
{
    ciphered_character -= 26;
}

Running the program with plaintext of z and a key of 26 causes 26 to be added to z (which is represented by 122). This causes plaintext[character] to overflow (past 127, I presume) and become negative before the while loop even kicks in. This gives a garbage output.

I know I can check for potential overflows beforehand and subtract 26 first, but that complicates my code. Can I give the variable 'more room' to prevent it from overflowing?

Do I use a different data type? What is the best practice here?


Solution

  • If you only care about lower case then this will work for you:

    for each character in plaintext:
       plaintext[character] = (plaintext[character] - 'a' + key) % 26 + 'a'
    

    Subtracting 'a' to give you a value of 0-25, then add the key. If there is a overflow the modulo will give you the updated value in the 0-25 range which is added back to 'a' to get the correct character.

    If you do need to handle both upper and lower case then you will need two different cases - one using 'a' and the other using 'A'. Select the the correct case for each character by checking isupper(plaintext[character])