Ok, let's try this again, step by step.

Any caesar cypher performs a transformation

Code:

cryptchar = (plainchar + shift) % alphabet_size

the inverse of this transformation is

Code:

plainchar = (cryptchar - shift) % alphabet_size

since the we are working with ASCII encoded characters we need to shift the origin from 0 to a before the transformation and back to 0 afterwards

Code:

plainchar = plainchar1 - 'a' // shift origin to a
cryptchar = (plainchar + shift) % alphabet_size
cryptchar1 = cryptchar + 'a' // shift origin back to 0

So far it's all really simple. The tricky bit is due to c++ implementation of the % operator. Usually modulus operations have range [0, n-1]. The c++ % operator has range [0, n-1] for positive input (the a in a % b) and [-n+1, 0] for negative input.

This is not an issue in the encryption since plainchar + shift is always positive (if the shift is positive, I'll show later that restricting the shift to the range [0, alphabet_size-1] still gives all possible shifts).

On the other hand on the decryption step there might be problems. If shift > cryptchar1 then cryptchar - shift will be a negative number which will give you a final result that is out of the intended range.

To solve this problem you need to ensure that cryptchar1 - shift is never negative.

One solution is to repeatedly add alphabet_size to the result untile the result is positive (since you are working in modulus arithmetic adding an integer multiple of alphabet_size doesn't change the final result).

The other soultion is to recognize the fact that (a - b) % c = (a + c - b) % c (remember adding any integer multiple of c doesn't change the result)

Thus the decryption routine can be written as

Code:

plainchar = (cryptchar + alphabet_size - shift) % alphabet_size

alphabet_size - shift is never negative as long as shift < alphabet_size

Why do you only need shifts in the range [0, alphabet_size - 1]?

Assume we have a bad_shift that is outside that range. We can break down bad shift into

Code:

bad_shift = a * alphabet_size + shift

where a is an arbitrary integer and 0 <= shift < alphabet_size.

Since we are working in modulus arithmetic the a * alphabet_size component has no effect to the final reusult and we can safely ignore it.

Hope this helps

PS

Originally Posted by

**L_U_K_E**
Code:

ciphertext += ( ( (a[i] - 'a') + (offset - offset2) / (offset3 * offset) - offset2) %26) + 'a';

I hope you realise that all those calculations with the 3 offsets could be done once and stored in a single variable