Implement a class that provides an encode and a decode method. The constructor w
ID: 3740562 • Letter: I
Question
Implement a class that provides an encode and a decode method. The constructor will take an array of integers representing position changes.
For the encode method, we will be embedding the secret message in a large text file.
The encode method will take a string message to encode, and a file name of a file to store the message in. It will open the file, then insert each word in the message into the file. For each word, the program will jump a number of bytes from the last position as indicated by the entries in the positions array. If it reaches the end of the positions array, it will loop back around to the first element, repeating until the words of the message have all be inserted into the file. It will then insert the string XXXX into the next position to indicate the end of the message.
For the decode method, we will be extracting the secret message from a large text file. The decode method will take the file name of the text file containing the message, and a reference to a stringstream object. It will jump to a position in the file, read a word, and load the word into the stringstream object until it encounters the XXXX end of message indicator.
Your driver program will take as command line parameters a command (encode or decode). If encode is indicated, it will also expect the file name of the text file to embed the message into, a text file with the position jumps (one number per line), and a file contanining the message to embed (in that order). If decode is indicated, the program will expect the file name of the file containing the message, and a file containing the position jumps (as indicated earlier), and will output the message to the screen.
encode loremipsum.txt positions.txt message.txt
de code loremipsum.txt positions.txt
You may assume that the positions file contains one number per line (but still should validate that they are numbers), and that the message consists of a single line in the message file.
c++
Explanation / Answer
#include "iostream"
#include <fstream>
#include <sstream>
#include <string>
#include <vector>
#define MAX_SIZE 255
#define END_STRING "XXXX"
using namespace std;
const string encode = "encode";
const string decode = "decode";
class crypto
{
private:
int m_positions[MAX_SIZE];
public:
crypto(int positions[MAX_SIZE])
{
for(int i = 0; i < MAX_SIZE; i++)
{
m_positions[i] = positions[i];
}
}
/*
The encode method will take a string message to encode, and a file name of a file to store the message in.
It will open the file, then insert each word in the message into the file.
For each word, the program will jump a number of bytes from the last position as indicated by the entries in the
positions array. If it reaches the end of the positions array, it will loop back around to the first element,
repeating until the words of the message have all be inserted into the file. It will then insert the string XXXX
into the next position to indicate the end of the message.
*/
void encode(string message, string fileName)
{
// split message into words/tokens to insert in the file.
stringstream msgStream(message);
vector<string> words;
string buffer;
while(msgStream >> buffer)
words.push_back(buffer);
if(words.size() == 0)
return;
// open file to write in
fstream *outFile = new fstream();
outFile->open(fileName, ios::out | ios::binary); // open in write and binary mode
if(outFile->is_open())
{
for(int i = 0, j = 0; i < words.size(), j < MAX_SIZE; i++, j++)
{
if(i == words.size())
break;
if(m_positions[j] == -1)
j = 0; // reset to starting position
int position = m_positions[j];
if(i == 0)
outFile->seekp(position, ios::beg);
else
outFile->seekp(position, ios::cur);
outFile->write(words[i].c_str(), words[i].length());
}
outFile->write(END_STRING, sizeof(END_STRING)); // add XXXX to indicate end of msg
}
outFile->close();
}
/*
For the decode method, we will be extracting the secret message from a large text file.
The decode method will take the file name of the text file containing the message,
and a reference to a stringstream object. It will jump to a position in the file, read a word,
and load the word into the stringstream object until it encounters the XXXX end of message indicator.
*/
void decode(string filename, stringstream& streamObj)
{
// open file to write in
fstream* inFile = new fstream();
inFile->open(filename, ios::in | ios::binary); // open in READ and binary mode
if(inFile->is_open())
{
string word;
for(int i = 0; i < MAX_SIZE, !inFile->eof(); i++)
{
if(m_positions[i] == -1)
i = 0; // reset to starting position
int position = m_positions[i];
if(i == 0)
inFile->seekg(position, ios::beg);
else
inFile->seekg(position, ios::cur);
*inFile >> word;
if(word.find(END_STRING) != string::npos)
{
streamObj << word.substr(0, word.find(END_STRING));// << " ";
break;
}
streamObj << word;// << " ";
}
}
inFile->close();
}
};
int readMsgFile(string filename, string& msg)
{
fstream *inFile = new fstream();
inFile->open (filename, ios::in ); // open in read only mode
if(!inFile->is_open()) //check for file open
{
cout << "Cannot open the input file" << filename << endl;
return 0;
}
getline (*inFile, msg); // as stated, assumed msg will be one line and in first line
inFile->close();
return 1;
}
int readPositionFile(string filename, int positions[])
{
fstream *inFile = new fstream();
inFile->open (filename, ios::in ); // open in read only mode
if(!inFile->is_open()) //check for file open
{
cout << "Cannot open the input file"<< filename << endl;
return 0;
}
string line = "";
int i = 0; // as stated, assumed initial values
while ( getline (*inFile, line) )
{
if(i >= MAX_SIZE)
return 0;
positions[i] = atoi(line.c_str());
i++;
}
if(i < MAX_SIZE)
positions[i] = -1; // default value, to check later for valid position values
inFile->close();
return 1;
}
int main(int argc, char* argv[])
{
if(argc <= 2)
return 0; // no command specified
else
{
if(encode.compare(argv[1]) == 0)
{
// encode command is specified:
// read output filename, input position file, message file
if(argc < 5)
cout << "command line arguments are not proper" << endl;
else
{
string outFileName = argv[2];
string possitionFile = argv[3];
string msgFile = argv[4];
int positions[MAX_SIZE] = {0};
readPositionFile(possitionFile, positions);
crypto obj(positions);
string msg;
readMsgFile(msgFile, msg);
obj.encode(msg, outFileName);
}
}
else if(decode.compare(argv[1]) == 0)
{
// decode command is specified:
// read output filename, input position file, message file
if(argc < 4)
cout << "command line arguments are not proper" << endl;
else
{
//string outFileName = argv[2]; output msg to screen
string outFileName = argv[2];
string possitionFile = argv[3];
int positions[MAX_SIZE] = {0};
readPositionFile(possitionFile, positions);
crypto obj(positions);
stringstream streamObj;
obj.decode(outFileName, streamObj);
cout << streamObj.str();
}
}
}
return 0;
}
Related Questions
drjack9650@gmail.com
Navigate
Integrity-first tutoring: explanations and feedback only — we do not complete graded work. Learn more.