Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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?

like image 537
yeojunjie Avatar asked Jan 01 '26 03:01

yeojunjie


2 Answers

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])

like image 77
jmq Avatar answered Jan 03 '26 17:01

jmq


Fun project;

I did it like this, assuming ASCII and using the full range of printable characters, from Space to ~

void caeser_shift(char* text, int key)
{ while (*text) { *text++ = ((*text-' ') + key) %('~'-' ') + ' '; } }

int main(void)
{
    char plaintext[] = "Hello World; This is a test.";

    caeser_shift(plaintext, 26);

    printf("%s\n", plaintext);

    return 0;
}

Output

Success #stdin #stdout 0s 4520KB
b!((+:q+.( U:n$%/:%/:{:0!/0H
like image 21
abelenky Avatar answered Jan 03 '26 18:01

abelenky



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!