# Shorten this Caesar Cipher cracker

My program has to decrypt ciphertext. It has to try all possible 26 shifts and store each in an array so that I calculate the frequencies of each array and find the highest frequency, in which that would result in the plain text.

#include <stdio.h>
#define CIPHERSIZE 42

char decryptCiphertext(char data[], double data2[]);
char likelyPlaintext (char decrypt[], double data2[]);

int main (void)
{
char cipher[43];

printf("\t===========================\n");
printf("  \t   DECRYPTING CIPHERTEXT\n");
printf("\t===========================\n");

FILE *ciphertext;
ciphertext = fopen("ciphertext.txt", "r");

if (ciphertext != NULL)
{
while (!feof(ciphertext))
fscanf(ciphertext, "%s", cipher);
fclose(ciphertext);
}
else
printf("Error opening file\n");
printf("Ciphertext : %s\n", cipher);

FILE *frequency;

double freq[26];
double num;
int i;
frequency = fopen("frequencies.dat", "r");
if (frequency == NULL)
printf("Error opening file\n");

for (i=0; i < 26; i++)
{
fscanf(frequency, "%lf", &freq[i]);
//printf("%lf\n", freq[i]);
}

fclose(frequency);
decryptCiphertext(cipher, freq);
}
char decryptCiphertext(char data[], double data2[])
{
int i, convert, shiftingLetter;
char decrypted26[42], decrypted1[42], decrypted2[42], decrypted3[42], decrypted4[42],
decrypted5[42], decrypted6[42], decrypted7[42], decrypted8[42], decrypted9[42], decrypted10[42],
decrypted11[42], decrypted12[42], decrypted13[42], decrypted14[42], decrypted15[42], decrypted16[42],
decrypted17[42], decrypted18[42], decrypted19[42], decrypted20[42], decrypted21[42], decrypted22[42],
decrypted23[42], decrypted24[42], decrypted25[42];

//Try all possible shifts from 1-25 and store each in an array
for (i = 0; data[i] != '\0'; i++)
{
convert = data[i] - 'A';  //convert letters to equal 0-26 ex:A=0,B=1,C=2,etc
convert = (convert + 1);    //add shift
shiftingLetter = convert % 26;    //cycle around
decrypted1[i] = 'A' + shiftingLetter;  //store new letter in array
}
decrypted1[i] = '\0';
likelyPlaintext(decrypted1, data2);
//printf(" 1. %s\n", decrypted1);

for (i = 0; data[i] != '\0'; i++)
{
convert = data[i] - 'A';
convert = (convert + 2);
shiftingLetter = convert % 26;
decrypted2[i] = 'A' + shiftingLetter;
}
decrypted2[i] = '\0';
//printf(" 2. %s\n", decrypted2);

for (i = 0; data[i] != '\0'; i++)
{
convert = data[i] - 'A';
convert = (convert + 3);
shiftingLetter = convert % 26;
decrypted3[i] = 'A' + shiftingLetter;
}
decrypted3[i] = '\0';
//printf(" 3. %s\n", decrypted3);

for (i = 0; data[i] != '\0'; i++)
{
convert = data[i] - 'A';
convert = (convert + 4);
shiftingLetter = convert % 26;
decrypted4[i] = 'A' + shiftingLetter;
}
decrypted4[i] = '\0';
//printf(" 4. %s\n", decrypted4);

for (i = 0; data[i] != '\0'; i++)
{
convert = data[i] - 'A';
convert = (convert + 5);
shiftingLetter = convert % 26;
decrypted5[i] = 'A' + shiftingLetter;
}
decrypted5[i] = '\0';
//printf(" 5. %s\n", decrypted5);

for (i = 0; data[i] != '\0'; i++)
{
convert = data[i] - 'A';
convert = (convert + 6);
shiftingLetter = convert % 26;
decrypted6[i] = 'A' + shiftingLetter;
}
decrypted6[i] = '\0';
//printf(" 6. %s\n", decrypted6);

for (i = 0; data[i] != '\0'; i++)
{
convert = data[i] - 'A';
convert = (convert + 7);
shiftingLetter = convert % 26;
decrypted7[i] = 'A' + shiftingLetter;
}
decrypted7[i] = '\0';
//printf(" 7. %s\n", decrypted7);

for (i = 0; data[i] != '\0'; i++)
{
convert = data[i] - 'A';
convert = (convert + 8);
shiftingLetter = convert % 26;
decrypted8[i] = 'A' + shiftingLetter;
}
decrypted8[i] = '\0';
//printf(" 8. %s\n", decrypted8);

for (i = 0; data[i] != '\0'; i++)
{
convert = data[i] - 'A';
convert = (convert + 9);
shiftingLetter = convert % 26;
decrypted9[i] = 'A' + shiftingLetter;
}
decrypted9[i] = '\0';
//printf(" 9. %s\n", decrypted9);

for (i = 0; data[i] != '\0'; i++)
{
convert = data[i] - 'A';
convert = (convert + 10);
shiftingLetter = convert % 26;
decrypted10[i] = 'A' + shiftingLetter;
}
decrypted10[i] = '\0';
//printf(" 10. %s\n", decrypted10);

for (i = 0; data[i] != '\0'; i++)
{
convert = data[i] - 'A';
convert = (convert + 11);
shiftingLetter = convert % 26;
decrypted11[i] = 'A' + shiftingLetter;
}
decrypted11[i] = '\0';
//printf(" 11. %s\n", decrypted11);

for (i = 0; data[i] != '\0'; i++)
{
convert = data[i] - 'A';
convert = (convert + 12);
shiftingLetter = convert % 26;
decrypted12[i] = 'A' + shiftingLetter;
}
decrypted12[i] = '\0';
//printf(" 12. %s\n", decrypted12);

for (i = 0; data[i] != '\0'; i++)
{
convert = data[i] - 'A';
convert = (convert + 13);
shiftingLetter = convert % 26;
decrypted13[i] = 'A' + shiftingLetter;
}
decrypted13[i] = '\0';
//printf(" 13. %s\n", decrypted13);

for (i = 0; data[i] != '\0'; i++)
{
convert = data[i] - 'A';
convert = (convert + 14);
shiftingLetter = convert % 26;
decrypted14[i] = 'A' + shiftingLetter;
}
decrypted14[i] = '\0';
//printf(" 14. %s\n", decrypted14);

for (i = 0; data[i] != '\0'; i++)
{
convert = data[i] - 'A';
convert = (convert + 15);
shiftingLetter = convert % 26;
decrypted15[i] = 'A' + shiftingLetter;
}
decrypted15[i] = '\0';
//printf(" 15. %s\n", decrypted15);

for (i = 0; data[i] != '\0'; i++)
{
convert = data[i] - 'A';
convert = (convert + 16);
shiftingLetter = convert % 26;
decrypted16[i] = 'A' + shiftingLetter;
}
decrypted16[i] = '\0';
//printf(" 16. %s\n", decrypted16);

for (i = 0; data[i] != '\0'; i++)
{
convert = data[i] - 'A';
convert = (convert + 17);
shiftingLetter = convert % 26;
decrypted17[i] = 'A' + shiftingLetter;
}
decrypted17[i] = '\0';
//printf(" 17. %s\n", decrypted17);

for (i = 0; data[i] != '\0'; i++)
{
convert = data[i] - 'A';
convert = (convert + 18);
shiftingLetter = convert % 26;
decrypted18[i] = 'A' + shiftingLetter;
}
decrypted18[i] = '\0';
//printf(" 18. %s\n", decrypted18);

for (i = 0; data[i] != '\0'; i++)
{
convert = data[i] - 'A';
convert = (convert + 19);
shiftingLetter = convert % 26;
decrypted19[i] = 'A' + shiftingLetter;
}
decrypted19[i] = '\0';
//printf(" 19. %s\n", decrypted19);

for (i = 0; data[i] != '\0'; i++)
{
convert = data[i] - 'A';
convert = (convert + 20);
shiftingLetter = convert % 26;
decrypted20[i] = 'A' + shiftingLetter;
}
decrypted20[i] = '\0';
//printf(" 20. %s\n", decrypted20);

for (i = 0; data[i] != '\0'; i++)
{
convert = data[i] - 'A';
convert = (convert + 21);
shiftingLetter = convert % 26;
decrypted21[i] = 'A' + shiftingLetter;
}
decrypted21[i] = '\0';
//printf(" 21. %s\n", decrypted21);

for (i = 0; data[i] != '\0'; i++)
{
convert = data[i] - 'A';
convert = (convert + 22);
shiftingLetter = convert % 26;
decrypted22[i] = 'A' + shiftingLetter;
}
decrypted22[i] = '\0';
//printf(" 22. %s\n", decrypted22);

for (i = 0; data[i] != '\0'; i++)
{
convert = data[i] - 'A';
convert = (convert + 23);
shiftingLetter = convert % 26;
decrypted23[i] = 'A' + shiftingLetter;
}
decrypted23[i] = '\0';
//printf(" 23. %s\n", decrypted23);

for (i = 0; data[i] != '\0'; i++)
{
convert = data[i] - 'A';
convert = (convert + 24);
shiftingLetter = convert % 26;
decrypted24[i] = 'A' + shiftingLetter;
}
decrypted24[i] = '\0';
//printf(" 24. %s\n", decrypted24);

for (i = 0; data[i] != '\0'; i++)
{
convert = data[i] - 'A';
convert = (convert + 25);
shiftingLetter = convert % 26;
decrypted25[i] = 'A' + shiftingLetter;
}
decrypted25[i] = '\0';
//printf(" 25. %s\n", decrypted25);

}
char likelyPlaintext (char decrypt[], double frequencies[])
{
int i;

for (i = 0; i < 26; i++)
printf("%lf\n", frequencies[i]);
printf("First shift : %s\n", decrypt);

for (i = 0; i <

}

• Create a structure for decrypted<i>[]? Commented Apr 8, 2013 at 0:29
• I don't understand how to finish the last function likelyPlaintext it has to take all the arrays in the decryptCiphertext function and find the frequency for each after that it has to see the greatest frequency and that results in being the plaintext. Commented Apr 8, 2013 at 0:44
• Write a function containing the for-loop and call it 26 times instead of repeating the for loop. Commented Apr 8, 2013 at 2:26
• You don't have to create all 26 "decryptions" of the string! Only create ONE (or use the ciphertext itself)! Then do the distribution of letters array - then shift THAT array to find your "target" distribution... Commented Nov 5, 2013 at 21:12
• You have figured out loops. Why can't you put a loop inside a loop. Commented Nov 5, 2013 at 21:21

decryptCiphertext can be reduced to

char decryptCiphertext(char data[], double data2[])
{
int i, shift, convert, shiftingLetter;
char decrypted[26][CIPHERSIZE];

for (shift = 1; shift < 26; shift++)
{
//Try all possible shifts from 1-25 and store each in an array
for (i = 0; data[i] != '\0'; i++)
{
convert = data[i] - 'A';  //convert letters to equal 0-26 ex:A=0,B=1,C=2,etc
convert = (convert + shift);    //add shift
shiftingLetter = convert % 26;    //cycle around
decrypted[shift][i] = 'A' + shiftingLetter;  //store new letter in array
}
decrypted[shift][i] = '\0';
likelyPlaintext(decrypted[shift], data2);
}
}

• Note that you could just decrypted[shift][i] = 'A' + (data[i] - 'A' + shift) % 26; Commented Apr 8, 2013 at 17:24

In fact, my comment up there is basically saying don't use the algorithm you're using now, instead use the normal "CryptoQuiz" algorithm your grandma has been using for 100 years to solve crypto-quiz puzzles in the newspaper (those were a printed version of the news, typically delivered to your door).

So, I'm saying, implement #2 in this tutorial on crypto-grams: http://www.cryptograms.org/tutorial.php

This method works on ANY substitution ciphers, not just the "simple" type you are dealing with.

IF your assignment requires you to use the algorithm given, just let me know and I'll change this answer.