////////////////////////////////////////////////////////////////////////////////// //// CAESAR.CPP - Assignment #6 //// by flamingspinach //// //// CS 161 "Computer Science I" (CRN #30496) //// //// started | 2005-07-21 21:42:37 //// finished | 2005-07-22 01:20:07 //// | //// devenv | Bloodshed Dev-C++ 4.9.9.2 //// sources | http://www.lookuptables.com/ - ASCII table //// //////////////////////////////////////////////////////////////////////////////////#include <iostream> // For terminal ops#include <fstream> // For file ops#include <string> // For string opsusing namespace std;int main () { // Declarations ifstream fi; ofstream fo; string pathname; int charFrequency[26] = {0}; char a; int i, j, rotOffset; // Open the files cout << "Please enter the path of the text to be decrypted: "; cin >> pathname; fi.open(pathname.c_str(), ifstream::in | ifstream::binary); if (! fi.is_open()) { // Check to see if it worked cout << "File not found." << endl; cin.get(); // Allow user to read output return 1; // Error exit code } cout << "Please enter the desired path of the decrypted file: "; cin >> pathname; fo.open(pathname.c_str(), ofstream::out | ofstream::trunc | ofstream::binary); if (! fo.is_open()) { cout << "File not found." << endl; // Check to see if it worked cin.get(); // Allow user to read output return 1; // Error exit code } // Check for most frequent letter fi.seekg(0, ios_base::beg); // Go to beginning of file while (fi) { a = fi.get() & ~0x20; // This will convert any lowercase characters to uppercase if (0x41 <= a && a <= 0x5A) charFrequency[a - 0x41]++; // Count the frequency of particular letters } for (i = (j = 0); i <= 25; i++) if (charFrequency[i] > charFrequency[j]) j = i; // Find the most frequent letter rotOffset = 30 - j; // 'E' is character 4 in a 0-based array, want a positive offset so 26 + 4 = 30 // Decrypt the file fi.clear(); // Reset EOF flag fi.seekg(0, ios_base::beg); // Go to beginning of input file a = fi.get(); // Get first character while (fi) { if (0x41 <= (a & ~0x20) && (a & ~0x20) <= 0x5A) // Convert to uppercase and check for range of uppercase ASCII chars a = ((a & ~0xE0) + rotOffset - 1) % 26 + 1 + (a & 0xE0); // Take the last five bits (upon which the alphabet in ASCII runs from 00001 to 11010, regardless of case) and convert to 0-based by subtracting one, then rotate by adding rotOffset and using % 26, then add the one back in to return to a valid ending 5 bits to the ASCII code for the new character, which is completed by adding back in the first three bits from the encrypted character, which incidentally preserves case fo.put(a); a = fi.get(); // This must be at the end of the loop because we don't want a spurious EOF character } fi.close(); fo.close(); cout << "Done." << endl; // Lead-out cin.ignore(65535, '\n').get(); // Allow user to read output return 0; // Clean exit code }