I have been working on the problem sets at Project Euler for some time and have enjoyed the challenges presented. I am currently on Problem 59 which involves the process of encryption and decryption.
The problem is, by any reasonable standard, a very simple decryption problem.
- I have been told that the encryption key consists of 3 lowercase letters.
- I have been given a description of the encryption/decryption process.
- I have been given an encrypted text file which contains only encrypted common English words
I fully understand the process of importing the data, cycling through all possible keys, and attempting to decrypt the file data with each possible key. My trouble is, after a decryption attempt with one of the keys, how can I tell if that key was the correct decryption key? As far as the computer is concerned, every decryption key just converts the data from one value to another. The meaning of that value is purely subjective/interpreted. How can I tell if a decryption key has decrypted the data into something meaningful (ie. common English words)
Here is the code I have so far (C#):
static void Main(string[] args)
{
/* Get the data from the file and convert to byte array*/
StreamReader inData = new StreamReader(@"C:\Users\thantos\Desktop\cipher1.txt");
string[] strData = inData.ReadLine().Split(new char[] {','});
byte[] fileData = new byte[strData.Length];
foreach (string x in strData) { byte.Parse(x); }
/* for each three character lowercase password */
for (uint i = 0; i < 26; i++) {
for (uint j = 0; j < 26; j++){
for (uint k = 0; k < 26; k++) {
/* create a key */
byte[] key = new byte[3];
key[0] = (byte)(i + 97);
key[1] = (byte)(j + 97);
key[2] = (byte)(k + 97);
/* create temp copy of data */
byte[] dataCopy = new byte[fileData.Length];
fileData.CopyTo(dataCopy, 0);
/* decrypt using key */
for (uint l = 0; l < dataCopy.Length; l++) {
dataCopy[l] = (byte)(dataCopy[l] ^ key[l%key.Length]);
}
/* cannot figure out how to check
* if data is meaningfully decrypted
*/
bool dataIsMeaningful = isMeaningful(dataCopy);
if(dataIsMeaningful) {
/* do stuff with data if correct
* decryption key was found
*/
}
}
}
}
}
I have tried this method for isMeaningful():
public static isMeaningful(byte[] inData) {
bool isGood = true;
for (uint i = 0; good && i < inData.Length; i++) {
isGood &= (char.IsLower((char)inData[i]));;
}
return isGood;
}
But it returns true for all 17576 possible keys.
How can I determine if the decryption key has decrypted the file data into meaningful data? I’m not looking for solution code or the answer to the Project Euler problem, I am looking for an explanation of how to check that your decryption attempt was successful.
Try different keys and score them against the letter frequency of normal English: space, followed by E, T, A, O, I, N, S, H, R, D, L, U. Pick the highest scoring keys first for a trial.