C++ Caesar Cipher

profileARapSal
caesarcipher.docx

Program Overview:

Variables:

Functions Called:

NONE

===============================================================================================================*/

/*===============================================================================================================

Assumptions about the arguments

1. Arguments input are specified with a single "\", such as c:\dissertation\cipher.txt

2. All files are of the type - txt

3. All files are found in c:\dissertation

===============================================================================================================*/

// Start with the inclusion of libraries

#include <iostream> //The library of io functions

#include <fstream> //The library of external stream functions

#include <cstdlib> //The library for external errors

#include <string> //The library for string functions

#include <cmath> //The library of C math functions

#include <stdlib.h>

#include <stdio.h>

#include <iomanip>

#include <time.h> //The clock timing function

#include <vector>

using namespace std;

//Function prototypes

char cleancharinfile(char letter);

string decryptfileshift(string& file, int key);

string decryptshift(char letter, int key);

string encryptshift(char letter, int key);

bool is_allowed(string mgram, vector<string>& alloweds);

void pause(string place); //Pauses the program for the user

void printvectorstring(vector<string>& data);

void readalloweds(string file, vector<string>& mgrams);

void timestampout(time_t start);

void timestampout(time_t start, ofstream& outs);

//The main function with command line arguments

int main(int argc, char* argv[])

{

int charcount = 0;

int dot = 10000; // Print out a character for every number of dot characters

int key;

int alpha;

int t;

int keycount = 25;

int foundkey;

int keypossible[26] = {0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1};

char letter;

char dateStr[9];

char timeStr[9];

ifstream ins; //The input stream

ofstream outs; //The output stream

string concat;

string file;

string deflt = "..\\data.txt"; //The default input file

string ofile1 = "..\\cipher.txt"; //The default output file

string ifile1; //Holds the input filename read

string cmdarg;

string threegram;

string fivegram;

string filefrag;

string goodfilefrag;

string recordfile;

vector<string> threes;

vector<string> fives;

//Decide if we have arguments or must use defaults

if(argc == 1)

{

// cout << "No argument found.\n";

ifile1 = deflt;

}

else

{

for(int loop=1; loop < argc; loop++)

{

cmdarg = argv[loop];

// cout << cmdarg << endl;

if(cmdarg == "-k")

{

loop++;

key = atoi(argv[loop]);

}

if(cmdarg == "-i")

{

loop++;

ifile1 = argv[loop];

}

if(cmdarg == "-o")

{

loop++;

ofile1 = argv[loop];

// cout << "Output file is " << ofile1 << endl;

}

}

}

ins.open(ifile1.c_str(),ios::binary); // Open the input stream as a binary input stream

if(ins.fail()) // If the input stream cannot open, report it then close the program

{

cerr << "\n\n ERROR - Cannot open " << ifile1 << " for reading.\n";

// return EXIT_FAILURE; //failure return

}

else {

std::cout << "\nOpened the file " << ifile1 << ".\n";

}

srand((unsigned)time(0));

key = (rand() % 25) + 1;

cout << "Key is " << key << endl;

cout << "Get file\n";

ins >> letter;

charcount = 0;

while(!ins.eof()){

// cout << letter;

letter = cleancharinfile(letter);

concat = encryptshift(letter, key);

file = file + concat;

if(charcount % dot == 0){

cout << ".";

}

ins >> letter;

charcount++;

}

cout << endl << endl;

//Read in 3 grams

readalloweds("../allowed3.bin", threes);

//Read in 5 grams

readalloweds("../allowed5.bin", fives);

// cout << file << endl << endl;

time_t seconds_start;

time_t time_now;

time_t start,now,end;

cout << "Start timing\n";

seconds_start = time (NULL);

time(&start);

now = time(NULL);

strftime(dateStr, 9, "%m/%d/%y", localtime(&now));

strftime(timeStr, 9, "%H:%M:%S", localtime(&now));

cout << "The date is " << dateStr << " and the time is " << timeStr << endl;

strftime(dateStr, 9, "%m-%d-%y", localtime(&now));

recordfile = dateStr;

strftime(timeStr, 9, "%H %M %S", localtime(&now));

recordfile = recordfile + " " + timeStr;

time_t rawtime;

time_t seco;

struct tm * timeinfo;

time ( &rawtime );

timeinfo = localtime ( &rawtime );

string strdata;

string timestamp;

strdata = asctime(timeinfo);

cout << strdata << endl;

recordfile = recordfile +".bin";

cout << recordfile << endl;

outs.open(recordfile.c_str(),ios::binary); // Open the output stream as a binary input stream

if(outs.fail()) // If the input stream cannot open, report it then close the program

{

cerr << "\n\n ERROR - Cannot open " << recordfile << " for writing.\n";

// return EXIT_FAILURE; //failure return

}

else {

std::cout << "\nOpened the output file " << recordfile << ".\n";

}

cout << "Begin the loop\n";

while(keycount > 1){

for(int loopcntr = 1;loopcntr < file.length(); loopcntr++){

filefrag = file.substr(0,loopcntr);

if(keycount > 1){

for(alpha = 1; alpha < 26; alpha++){ //alpha is the key being checked

if(keypossible[alpha] == 1){

// cout << "Decrypt the message with the key under consideration. Key of " << alpha << "\n";

string ans = decryptfileshift(filefrag,alpha);

goodfilefrag = ans;

if(ans.length() >= 3){

// cout << "Form 3-gram\n";

threegram = ans.substr(ans.length()-3,3);

// cout << threegram << endl;

if(!is_allowed(threegram,threes)){

keypossible[alpha] = 0;

// cout << "Eliminated key " << alpha << " from consideration.\n";

keycount = keycount - 1;

}

}

if((ans.length() >= 5) && (keypossible[alpha] == 1)){

// cout << "Form 5-gram\n";

fivegram = ans.substr(ans.length()-5,5);

// cout << fivegram << endl;

if(!is_allowed(fivegram,fives)){

keypossible[alpha] = 0;

// cout << "Eliminated key " << alpha << " from consideration.\n";

keycount = keycount - 1;

}

}

// cout << keycount << endl;

// cout << ans << endl;

}

}

}

else{

break;

}

}

}

cout << "End timing\n";

now = time(NULL);

time(&end);

double elapsed = difftime(end,start);

cout << "Run time is " << elapsed *1000/CLOCKS_PER_SEC << endl;

t = clock();

cout << "Time from clock = " << (float)t/CLOCKS_PER_SEC << " seconds." << endl;

strdata = asctime(timeinfo);

cout << strdata << endl;

cout << "Record results\n";

cout << "Report results\n";

for(int loop = 1; loop < 26; loop++){

if(keypossible[loop] == 1){

foundkey = loop;

}

}

//Data written out as sucess,key,key found,number of chars to solve,input filename,time to solve

if(key == foundkey){

cout << "Correct Key Found! Found key " << foundkey << " in " << goodfilefrag.length() - 1 << " characters.\n";

outs << "1," << key << "," << foundkey << "," << goodfilefrag.length()-1 << "," << ifile1 << "," << elapsed *1000/CLOCKS_PER_SEC << endl;

}

else{

cout << "Incorrect Key Found! Found key " << foundkey << " instead of " << key << " in " << goodfilefrag.length() - 1 << " characters.\n";

outs << "0," << key << "," << foundkey << "," << goodfilefrag.length()-1 << "," << ifile1 << "," << elapsed *1000/CLOCKS_PER_SEC << endl;

}

//Close the input and output files

ins.close();

outs.close();

cout << "Closed the files, this program is done.\n";

return 0;

}

/*================================================================================================================

End of main program

==================================================================================================================*/

string decryptshift(char letter, int key)

{

int newletter;

string eletter = "";

newletter = int(letter) - key;

if(newletter < 97){

newletter = newletter + 26;

}

if(newletter >= 97 && newletter <= 122){

eletter = char(newletter);

}

return eletter;

}

string decryptfileshift(string& file, int key)

{

int loop;

string dfile;

for(loop = 0;loop < file.length(); loop++){

// cout << file[loop] << endl;

dfile = dfile + decryptshift(file[loop],key);

}

return dfile;

}

string encryptshift(char letter, int key)

{

int newletter;

string eletter = "";

newletter = int(letter) + key;

if(newletter > 122){

newletter = newletter - 26;

}

if(newletter >= 97 && newletter <= 122){

eletter = char(newletter);

}

return eletter;

}

char cleancharinfile(char letter)

{

char symbol;

char concat;

symbol = tolower(letter);

if((int(symbol) >= 97) && (int(symbol) <= 122)){

concat = symbol;

}

else{

concat = char("");

}

return concat;

}

bool is_allowed(string mgram, vector<string>& alloweds)

{

bool success = false;

vector<string>::iterator ptr;

for(ptr = alloweds.begin(); ptr < alloweds.end(); ptr++){

if(*ptr == mgram){

success = true;

break;

}

if(*ptr > mgram){

break;

}

}

return success;

}

/*=================================================================================================================

Function void pause(string place)

Created 9/25/2003

Function Overview: Writes the message out to the user found in the input argument. Then wait for a non-whitespace

character. When received, continue program execution. This function is normally used in debug to give data to

the user and to stop the program until the user wishes to continue.

Variables used:

dummy char Holds the non-whitespace character to be entered

place string The message to send to the user

Functions called: None

===================================================================================================================*/

void pause(string place)

{

char dummy;

//Write a message out to the user, prompt the user for an input. When the user enters a non-whitespace

// character, continue execution of the program.

cout << endl << endl;

cout << "This is a planned pause. "<< place << "\n\nEnter a non-whitespace character here. -> ";

cin>>dummy;

cout << endl << endl << endl;

}

void printvectorstring(vector<string>& data)

{

vector<string>::iterator ptr;

for(ptr = data.begin(); ptr < data.end(); ptr++){

cout << *ptr << endl;

}

}

void readalloweds(string file, vector<string>& mgrams)

{

int count = 0;

string gram;

ifstream ins;

ins.open(file.c_str(),ios::binary); // Open the input stream as a binary input stream

if(ins.fail()) // If the input stream cannot open, report it then close the program

{

cerr << "\n\n ERROR - Cannot open " << file << " for reading.\n";

// return EXIT_FAILURE; //failure return

}

else {

std::cout << "\nOpened the file " << file << ".\n";

}

ins >> gram;

while(!ins.eof()){

mgrams.push_back(gram);

if(count % 10000 == 0){

cout << ".";

}

ins >> gram;

count++;

}

cout << endl;

ins.close();

// printvectorstring(mgrams);

}

void timestampout(time_t start, ofstream& outs)

{

int hours, min, sec;

time_t now;

time(&now);

char dateStr[9];

char timeStr[9];

now = time(NULL);

strftime(dateStr, 9, "%m/%d/%y", localtime(&now));

strftime(timeStr, 9, "%H:%M:%S", localtime(&now));

cout << "The date is " << dateStr << " and the time is " << timeStr << endl;

outs << "The date is " << dateStr << " and the time is " << timeStr << endl;

hours = difftime(now,start)/3600;

min = (difftime(now,start) - (hours*3600))/60;

sec = difftime(now,start) - (hours*3600) - (min*60);

cout << "Program has run for " << difftime(now,start) << " seconds. Or " << hours << " hour(s), " << min << " minute(s), and " << sec << " second(s).\n";

outs << "Program has run for " << difftime(now,start) << " seconds. Or " << hours << " hour(s), " << min << " minute(s), and " << sec << " second(s).\n";

int t = clock();

cout << "Time from clock = " << (float)t/CLOCKS_PER_SEC << " seconds." << endl;

}

void timestampout(time_t start)

{

int hours, min, sec, msec;

time_t now;

time(&now);

char dateStr[9];

char timeStr[9];

now = time(NULL);

strftime(dateStr, 9, "%m/%d/%y", localtime(&now));

strftime(timeStr, 9, "%H:%M:%S", localtime(&now));

cout << "The date is " << dateStr << " and the time is " << timeStr << endl;

hours = difftime(now,start)/3600;

min = (difftime(now,start) - (hours*3600))/60;

sec = difftime(now,start) - (hours*3600) - (min*60);

msec = difftime(now,start) - (hours*3600) - (min*60) - (sec*60);

cout << "Program has run for " << difftime(now,start) << " seconds. Or " << hours << " hour(s), " << min << " minute(s), and " << sec << " second(s).\n";

// cout << "milliseconds = " << msec << endl;

}