/**************************************************************************************** * Base 64 encoder/decoder written by Thomas Madsen 2012. * The source code and programs are provided 'as-is', without any express or implied warranty. * In no event will the author be held liable for any damages arising from the use of this software. * *****************************************************************************************/ #include #include #include #include #include #include #include using namespace std; string chartobinary8(char str) { unsigned int decimal = (int)str; unsigned int a[8]; stringstream ss; for (int i = 0; i <= 7; i++) { a[i] = decimal % 2; decimal = (decimal - a[i])/2; } for (int i =0; i <= 7; i++) { ss << a[7-i]; } return ss.str(); } char binarytochar8(string str) { string a[8]; unsigned int b[8]; int result = 0; for (int i = 0; i <= 7; i++) { a[i] = str.at(i); istringstream (a[i]) >> b[i]; result = result + b[i]*pow(2,7-i); } return (char)result; } string binarytochar6(string str) { string alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; string result; string a[6]; unsigned int b[6]; int r = 0; for (int i = 0; i <= 5; i++) { a[i] = str.at(i); istringstream (a[i]) >> b[i]; r = r + b[i]*pow(2,5-i); } result = alphabet.substr( r, 1); return result; } string chartobinary6(string str) { string alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; size_t found = alphabet.find(str); if (found != string::npos){ int decimal = int(found); unsigned int a[6]; stringstream ss; for (int i = 0; i <= 5; i++) { a[i] = decimal % 2; decimal = (decimal - a[i])/2; } for (int i =0; i <= 5; i++) { ss << a[5-i]; } return ss.str(); } else{ return "000000";} } int main(int argc, char* argv[]) { string FileNameIn = ""; // Name of the inputfile string FileNameOut = ""; // Name of the output file int filesize = 0; // For the filesiez int corfilesize = 0; // For corrected filesize unsigned char r[4]; // For reading. Uses r[3] for encoding. Uses r[4] for decoding. unsigned char w; // For writing int leftover; // For remainder of filesize divided by 3 string temp8; // For the routine string temp6; // For the routine string option; // For the encryp/decrypt option if (argc==4) // Check that we have three arguments { string option = argv[1]; // Get option '-e' for encryption and '-d' for decryption FileNameIn = argv[2]; // Get inputfile name FileNameOut = argv[3]; // Get outputfile name ifstream myFileIn (FileNameIn, ios::out | ios::binary); ofstream myFileOut (FileNameOut, ios::in | ios::binary | ios::trunc); if (option == "-e") { if(myFileIn.is_open()) // Check that file exists / is open { myFileIn.seekg(0, ios::end ); // Move to end of file filesize = myFileIn.tellg(); // Compute file size /**** Compute end *******/ leftover = filesize % 3; corfilesize = filesize - leftover; // This is divisible by 3 /************************/ cout << "Working ... this might take some time depending on the size of the file." << endl; for (int i =0; i <= corfilesize/3 - 1; i++) // Converts file { myFileIn.seekg(3*i, ios::beg); myFileIn >> noskipws >> r[0]; // Reads from file myFileIn >> noskipws >> r[1]; myFileIn >> noskipws >> r[2]; /********************************************/ temp8 = chartobinary8(r[0]) + chartobinary8(r[1]) + chartobinary8(r[2]); for (int j = 0; j <= 3; j++) { temp6 = temp8.substr(6*j,6); w = binarytochar6(temp6)[0]; myFileOut << w; // Writes to file } /********************************************/ } /********************************************/ if (leftover == 2) { myFileIn.seekg(corfilesize, ios::beg); // Go to the laft part of the end myFileIn >> noskipws >> r[0]; // Reads from file myFileIn >> noskipws >> r[1]; r[2] = 0; temp8 = chartobinary8(r[0]) + chartobinary8(r[1]) + chartobinary8(r[2]); for (int j = 0; j <= 2; j++) { temp6 = temp8.substr(6*j,6); w = binarytochar6(temp6)[0]; myFileOut << w; // Writes to file } myFileOut << '='; } if (leftover == 1) { myFileIn.seekg(corfilesize, ios::beg); // Go to the last part of the file myFileIn >> noskipws >> r[0]; // Reads from file r[1] = 0; r[2] = 0; temp8 = chartobinary8(r[0]) + chartobinary8(r[1]) + chartobinary8(r[2]); for (int j = 0; j <= 1; j++) { temp6 = temp8.substr(6*j,6); w = binarytochar6(temp6)[0]; myFileOut << w; // Writes to file } myFileOut << '='; myFileOut << '='; } /********************************************/ myFileIn.close(); // Closes input file myFileOut.close(); // Closes output file cout << "Succces!" << endl; return 0; } // End if open else {cout << "Error 1: Input file does not exist?"; return 1;} } // End if option == "-e"; else if (option == "-d"){ if(myFileIn.is_open()) // Check that file exists / is open { myFileIn.seekg(0, ios::end ); // Move to end of file filesize = myFileIn.tellg(); // Compute file size corfilesize = filesize - 4; myFileIn.seekg(0, ios::beg); // Go to the beginning of the file cout << "Working ... this might take some time depending on the size of the file." << endl; /*********************************************/ for (int i = 0; i <= corfilesize/4 -1; i++) { myFileIn >> noskipws >> r[0]; // Reads from file myFileIn >> noskipws >> r[1]; myFileIn >> noskipws >> r[2]; myFileIn >> noskipws >> r[3]; string rs[4]; rs[0] = r[0]; // Convert to string rs[1] = r[1]; rs[2] = r[2]; rs[3] = r[3]; temp6 = chartobinary6(rs[0]) + chartobinary6(rs[1]) + chartobinary6(rs[2])+ chartobinary6(rs[3]); for (int j = 0; j <= 2; j ++) { temp8 = temp6.substr(8*j, 8); w = binarytochar8(temp8); myFileOut << w; } } /**********The End Part **********************/ myFileIn.seekg(corfilesize, ios::beg); myFileIn >> noskipws >> r[0]; // Reads from file myFileIn >> noskipws >> r[1]; myFileIn >> noskipws >> r[2]; myFileIn >> noskipws >> r[3]; string rs[4]; rs[0] = r[0]; // Convert to string rs[1] = r[1]; rs[2] = r[2]; rs[3] = r[3]; temp6 = chartobinary6(rs[0]) + chartobinary6(rs[1]) + chartobinary6(rs[2])+ chartobinary6(rs[3]); int max = 0; if (rs[2] == "="){max = 1;} if (rs[2] != "="){max = 2;} for (int j = 0; j <= max-1; j ++) { temp8 = temp6.substr(8*j, 8); w = binarytochar8(temp8); myFileOut << w; } /*********************************************/ myFileIn.close(); // Closes input file myFileOut.close(); // Closes output file cout << "Succces!" << endl; } // End if open else {cout << "Error 2: Input file does not exist?"; return 1;} return 0; } // End if option == "-d" } // End if argv == 4 else{ // Else for if argv == 4 cout << "---------------------------------------------" << endl; cout << "Syntax: base64 [option] filein finleout" << endl; cout << "[option] is -e for encoding, -d for decoding." << endl;; cout << "---------------------------------------------"; return 0; } return 0; } // End int main