Done!
Anyone who has some time and experience, do check out the code and let me know what do you think of my coding style/errors/etc.
Code:
#include <cstdlib>
#include <iostream>
#include <string>
#include <fstream>
using namespace std;
void usage() {
cout << "xorc - XOR enCrypt" << endl << endl;
cout << "usage: xorc [-parameters] data|input_file key|key_file out_file" << endl;
cout << "example: xorc -iork input.txt ignored out.txt";
cout << endl << "xorc encrypts data with key if no parameters specified by XOR-ing them together\n";
cout << endl << "Parameters:" << endl << endl << "i - second argument is treated as input file";
cout << endl << "k - third argument is treated as key file";
cout << endl << " by default it adds a .xor after the extension, or removes it if found";
cout << endl << "x - replace with input file. remember to forget the key";
cout << endl << endl << endl << " Coded by izua, 11-aug-2007";
}
string xorstr(string data, string key) {
//this function XORs data with key, by repeating key if needed
int klen = key.length();
int dlen = data.size();
int z;
string result;
//process every character of data
for (z=0; z < dlen; z++) {
result += (key[z % klen] ^ data[z]);
//omg. this does the whole thing
//key[z % klen] gets the coresponding key-character for the current data character
//(repeats it if it's shorter than data. that is xored with current data character
//to get the result, which is added to a variable, called "result". lol @ above
}
//we're done, return
return(result);
}
string readfile(string filename) {
//reads a named file
string filedata;
//open the file in binary
ifstream fin(filename.c_str(),ios::binary);
char ch;
if (!fin.good()) {
//not good
cout << "\bError: Unable to open " << filename << endl;
fin.close();
return "xorcerr-can't open";
}
//get each character
while( fin.get( ch ) ) {
filedata += ch;
}
//done! cleanup and return
fin.close();
return filedata;
}
int main(int argc, char *argv[])
{
//main
bool arg_i=false;
bool arg_o=false;
bool arg_k=false;
bool arg_t=false;
bool arg_r=false;
bool arg_x=false;
bool arg=false;
string key = "";
string filename = "";
string buf = "";
string encdata = "";
string data = "";
//first, we check to see if we have parameters
string temp;
for (int z=0; z<argc; z++) {
temp=argv[z];
if (temp.substr(0,1) == "-") {
arg=true;
//set flags according to what parameters are passed
arg_i=(temp.find("i") != string::npos)?true:false;
arg_k=(temp.find("k") != string::npos)?true:false;
arg_x=(temp.find("x") != string::npos)?true:false;
//set vars according to determined parameter positions
}
}
//cout << "i" << arg_i << "k" << arg_k << "x" << arg_x << endl;
//check if parameters are correct
if (argc<4 or argc>5) {
//instruct the user how to do this, than terminate the app
usage();
goto hell;
} else {
if ((argc == 4 and arg == false) or argc == 5) {arg_o=true;}
//start doing something useful
//read input file (if any)
if (arg_i) {
cout << "Reading " << argv[2] << " into input" << endl;
data=readfile(argv[2]);
if (data=="xorcerr-can't open") goto hell;
if (data.length()<1) {cout << "Error: input file is invalid"; goto hell; }
} else {
//nope, we're not reading a file. input is second parameter if we have arguments, first if not
data=(arg)?argv[2]:argv[1];
}
//read key file if required
if (arg_k) {
cout << "Reading " << argv[2] << " into keyfile" << endl;
key=readfile(argv[3]);
if (key=="xorcerr-can't open") goto hell;
if (key.length()<1) {cout << "Error: the keyfile is invalid"; goto hell; }
} else {
//nope, we're not reading a file. input is second parameter if we have arguments, first if not
key=(arg)?argv[3]:argv[2];
}
//encrypt it. whoa. really long line
encdata = xorstr(data, key);
//this whole bunch of code computes a new filename - derived from input file if any, as output file if given
//or raises an error if no file given
//get filename passed (if any)
if (arg_o) {
//passed filename if supplied
filename=(arg)?argv[4]:argv[3];
} else if (arg_i and !arg_o) {
//input filename.xor if no output supplied
filename=((arg)?argv[2]:argv[1]);
//check if filename already has xor extension
if (filename.substr(filename.length()-4,4) == ".xor") {
//yes, it has. remove it
filename = filename.substr(0,filename.length()-4);
} else {
//neah, it doesn't have. add it
filename+=".xor";
}
} else if (!arg_i and !arg_o) {
cout << "Error: no file specified";
goto hell;
//error if neither input or output specified
}
//open the stream and write data
ofstream fout(filename.c_str(),ios::binary);
fout << encdata;
fout.close();
//announce end
cout << "Data written to " << filename << "!" << endl;
}
return EXIT_SUCCESS;
hell:
return EXIT_FAILURE;
}