Skip to content

Instantly share code, notes, and snippets.

@taycaldwell
Created April 8, 2014 02:18
Show Gist options
  • Save taycaldwell/10083512 to your computer and use it in GitHub Desktop.
Save taycaldwell/10083512 to your computer and use it in GitHub Desktop.
Decrypt plaintext by letter frequencies
#include <iostream>
#include <fstream>
#include <string>
#include <ctype.h>
using namespace std;
char freq[26] = {'E', 'T', 'A', 'O', 'I', 'N', 'S', 'H',
'R', 'D', 'L', 'C', 'U', 'M', 'W', 'F',
'G', 'Y', 'P', 'B', 'V', 'K', 'J', 'X',
'Q', 'Z'};
string getKey();
string getEncryptedMsg();
string getDecryptedMsg(int *key, string enMsg);
string getDecryptedMsg(string key, string enMsg);
int getScore(string deMsg);
int* initKey(int *msgFreq);
void initGuess(int* key, string enMsgStr);
void computeMsgFreq(string enMsgStr, int* msgFreq);
void printMsgFreq(string enMsgStr, int* msgFreq);
string getAlphaKey(int* key);
int getScore(string deMsg)
{
string word;
int score = 0;
ifstream file;
file.open("dictionary.txt");
while(!file.eof())
{
getline(file, word);
if (deMsg.find(word) != string::npos)
{
score++;
}
}
file.close();
return score;
}
string getDecryptedMsg(int *key, string enMsg)
{
string deMsg = "";
char msgArray[enMsg.size()];
strcpy(msgArray, enMsg.c_str());
for(int i = 0; i < enMsg.length(); i++)
{
deMsg.push_back(freq[key[toupper(msgArray[i]) - 'A']]);
}
return deMsg;
}
string getDecryptedMsg(string key, string enMsg)
{
string deMsg = "";
char msgArray[enMsg.size()];
strcpy(msgArray, enMsg.c_str());
for(int i = 0; i < enMsg.length(); i++)
{
deMsg.push_back(key[toupper(msgArray[i]) - 'A']);
}
return deMsg;
}
void initGuess(int* key, string enMsgStr)
{
int tempScore;
char tempChar;
int inc = 1;
int score = getScore(getDecryptedMsg(key, enMsgStr));
for(int i = 0; i < 26; i++)
{
if(i+inc <= 25)
{
tempChar = freq[i];
freq[i] = freq[i+inc];
freq[i+inc] = tempChar;
tempScore = getScore(getDecryptedMsg(key, enMsgStr));
if(score >= tempScore)
{
tempChar = freq[i];
freq[i] = freq[i+inc];
freq[i+inc] = tempChar;
}
else
{
score = tempScore;
}
}
}
}
int* initKey(int *msgFreq)
{
int *key = new int[26];
int j;
for(j = 0; j < 26; j ++)
{
int max = -1, indexOfMax = -1;
int i;
for(i = 0; i < 26; i++)
{
if(msgFreq[i] > max)
{
max = msgFreq[i];
indexOfMax = i;
}
}
msgFreq[indexOfMax] = -1;
key[indexOfMax] = j;
}
return key;
}
string getKey()
{
string key = "";
string upperKey = "";
cout << "\nEnter key (or 'quit' to quit):\n " << endl;
getline(cin, key);
for(int i = 0; i < key.size(); i++)
{
upperKey += toupper(key[i]);
}
return upperKey;
}
string getEncryptedMsg()
{
string msg, str;
ifstream file;
file.open("encrypted_message.txt");
while(!file.eof())
{
getline(file, str);
str = str.substr(0, str.length()-1);
msg.append(str);
}
file.close();
return msg;
}
void computeMsgFreq(string enMsgStr, int* msgFreq)
{
char enMsgArray[enMsgStr.size()];
strcpy(enMsgArray, enMsgStr.c_str());
for(int i = 0; i < enMsgStr.length(); i++)
{
msgFreq[toupper(enMsgArray[i]) - 'A']++;
}
}
void printMsgFreq(string enMsgStr, int* msgFreq)
{
cout << "\nOriginal Encrypted Message Frequencies:" << endl;
for(int i = 0; i < 26; i++)
{
cout << char(toupper(i) + 'A') << ": "
<< ((msgFreq[i] * 1.0 / enMsgStr.length() * 1.0 ) * 100.0)
<< '%' << endl;
}
}
string getAlphaKey(int* key)
{
string str = "";
for(int i = 0; i < 26; i++)
{
str.push_back(freq[key[i]]);
}
return str;
}
int main()
{
string enMsgStr = getEncryptedMsg();
int msgFreq[26] = {0};
computeMsgFreq(enMsgStr, msgFreq);
printMsgFreq(enMsgStr, msgFreq);
int *key = initKey(msgFreq);
cout << "\nDecrypting message...\n" << endl;
initGuess(key, enMsgStr);
cout << "Decrypted Message (using Key - " << getAlphaKey(key)
<< "):\n" << getDecryptedMsg(key, enMsgStr) << endl;
bool running = true;
while(running)
{
string keyStr = getKey();
if(keyStr != "QUIT")
{
cout << "Decrypted Message (using Key - " << keyStr << "):\n"
<< getDecryptedMsg(keyStr, enMsgStr) << endl;
}
else
{
running = false;
}
}
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment