If you want to read more about the Caesar cipher (especially the history behind it), you should probably see this.
For the C implementation we shall consider the following macrodefinitions, enumerations and libraries:
#include<stdio.h> #include<stdlib.h> #include<string.h> #include<ctype.h> #define SHIFT_MAX 26 #define NUMBER_OF_LETTERS 26 #define NUMBER_OF_DIGITS 10 #define CAESAR_CIPHER_SPECIAL_CHARS " .!?,;:'()[]{}`" typedef enum { OPERATION_SUCCESS = 1U, OPERATION_FAILED = 0U }OPERATION_STATUS;
1. The Encryption Algorithm
We shall consider E as the encrypted ASCII string and O as the "original" ASCII string. E is calculated using the formulas displayed below:
The original string : I AM CAESAR
The encrypted string: L DP FDHVDU
The C implementation:
The encrypted string: L DP FDHVDU
The decrypted string: I AM CAESAR
The C implementation:
By studying the output and using your common sense, you can easily observe that the only sentence that makes sense is the one where the shift value is equal to 3.Caesar cipher encryption formulas |
- Oi - the element at the i-th position in the original string.
- Ei - the element at the i-th position in the encrypted string.
- M - a predefined set of elements who will not be encrypted (this set will be contained in CAESAR_CIPHER_SPECIAL_CHARS).
- s - how many positions a letter or a digit will be shifted
- The "magic numbers" 97, 65 and 48 represent the ASCII codes of 'a', 'A' and '0', while 26 and 10 represent the number of letters of the English alphabet respectively the number of digits.
The original string : I AM CAESAR
The encrypted string: L DP FDHVDU
The C implementation:
OPERATION_STATUS CaesarCipher_Encrypt(const char* originalMessage, char* codedMessage, short shift) { unsigned int size = strlen(originalMessage); unsigned int i = 0; for(i=0; i<size; i++) { if(islower(originalMessage[i])) { codedMessage[i] = (((short)(originalMessage[i]-'a') + shift) %NUMBER_OF_LETTERS) + 'a'; } else if(isupper(originalMessage[i])) { codedMessage[i] = (((short)(originalMessage[i]-'A') + shift) %NUMBER_OF_LETTERS) + 'A'; } else if(isdigit(originalMessage[i])) { codedMessage[i] = ((short)(originalMessage[i]-'0') + shift) %NUMBER_OF_DIGITS + '0'; } else if(strchr(CAESAR_CIPHER_SPECIAL_CHARS, originalMessage[i])!=NULL) { codedMessage[i] = originalMessage[i]; } else { return OPERATION_FAILED; } } codedMessage[size] = '\0'; return OPERATION_SUCCESS; }
2. The Decryption Algorithm
We shall consider E as the encrypted string and O as the decrypted string. O is calculated using the formulas displayed below:- Oi - the element at the i-th position in the decrypted string.
- Ei - the element at the i-th position in the encrypted string.
- M - a predefined set of elements who will not be encypted (this set will be contained in CAESAR_CIPHER_SPECIAL_CHARS).
- s - how many positions a letter or a digit was shifted
- The "magic numbers" 97, 65 and 48 represent the ASCII codes of 'a', 'A' and '0', while 26 and 10 represent the number of letters of the English alphabet respectively the number of digits.
The encrypted string: L DP FDHVDU
The decrypted string: I AM CAESAR
The C implementation:
OPERATION_STATUS CaesarCipher_Decrypt(const char* codedMessage, char* originalMessage, short shift) { unsigned int size = strlen(codedMessage); unsigned int i = 0; for(i=0; i<size; i++) { if(islower(codedMessage[i])) { originalMessage[i] = (abs((short)(codedMessage[i]-'a') - shift) %NUMBER_OF_LETTERS) + 'a'; } else if(isupper(codedMessage[i])) { originalMessage[i] = (abs((short)(codedMessage[i]-'A') - shift) %NUMBER_OF_LETTERS) + 'A'; } else if(isdigit(codedMessage[i])) { originalMessage[i] = (abs((short)(codedMessage[i]-'0') - shift)) %NUMBER_OF_DIGITS + '0'; } else if(strchr(CAESAR_CIPHER_SPECIAL_CHARS, codedMessage[i])!=NULL) { originalMessage[i] = codedMessage[i]; } else { return OPERATION_FAILED; } } originalMessage[size] = '\0'; return OPERATION_SUCCESS; }
3. Breaking the Caesar's Cipher
Breaking Caesar's Cipher is not very complicated. For an encrypted string you have NUMBER_OF_LETTERS (normally 26) possible decrypted strings. Using the functions described above it will not be very complicated or time-consuming to generate all strings and figure out the shift value.char coded[30] = "L dp FDHVDU 5345!!!"; char message[30]; unsigned int i = 0; for(i=0; i<26;i++) { CaesarCipher_Decrypt(coded,message,i); printf("%s with shift value %d\n",message,i); } //Output //L dp FDHVDU 5345!!! with shift value 0 //K co ECGUCT 4234!!! with shift value 1 //J bn DBFTBS 3123!!! with shift value 2 //I am CAESAR 2012!!! with shift value 3 //H bl BBDRBQ 1101!!! with shift value 4 //G ck ACCQCP 0210!!! with shift value 5 //F dj BDBPDO 1321!!! with shift value 6 //E ei CEAOEN 2432!!! with shift value 7 //D fh DFBNFM 3543!!! with shift value 8 //C gg EGCMGL 4654!!! with shift value 9 //B hf FHDLHK 5765!!! with shift value 10 //A ie GIEKIJ 6876!!! with shift value 11 //B jd HJFJJI 7987!!! with shift value 12 //C kc IKGIKH 8098!!! with shift value 13 //D lb JLHHLG 9109!!! with shift value 14 //E ma KMIGMF 0210!!! with shift value 15 //F nb LNJFNE 1321!!! with shift value 16 //G oc MOKEOD 2432!!! with shift value 17 //H pd NPLDPC 3543!!! with shift value 18 //I qe OQMCQB 4654!!! with shift value 19 //J rf PRNBRA 5765!!! with shift value 20 //K sg QSOASB 6876!!! with shift value 21 //L th RTPBTC 7987!!! with shift value 22 //M ui SUQCUD 8098!!! with shift value 23 //N vj TVRDVE 9109!!! with shift value 24 //O wk UWSEWF 0210!!! with shift value 25