Using the Vigenere scrambler data type, we can define an object adapter
Ask Expert

Be Prepared For The Toughest Questions

Practice Problems

Using the Vigenere scrambler data type, we can define an object adapter

Problem 3

Using the Vigenere scrambler data type, we can define an object adapter that provides us with an input file stream for Vigenère ciphers. That is, this object adapter performs encoding and decoding on-the-fly while reading the contents of a file.

Assume the implementation of class Vigenere is correct. Using Vigenere, define class

iVigenereStream that satisfies the suggested specification as shown below:

#pragma once

#include <fstream>

#include <functional>

#include "Vigenere.h"

using Cipher = std::function<char ( Vigenere& aCipherProvider, char aCharacter )>;

class iVigenereStream

{

private:

std::ifstream fIStream; Vigenere fCipherProvider; Cipher fCipher;

public:

iVigenereStream( Cipher aCipher,

const std::string& aKeyword,

const char* aFileName = nullptr ); // [8]

~iVigenereStream(); // [2]

void open( const char* aFileName ); // [8]

void close(); // [2]

void reset(); // [10]

// conversion operator to bool

operator bool() { return !eof(); }

// stream positioning

uint64_t position() { return fIStream.tellg(); }

void seekstart() { fIStream.clear(); fIStream.seekg( 0, std::ios_base::beg ); }

bool good() const; // [3]

bool is_open() const; // [3]

bool eof() const; // [3]

iVigenereStream& operator>>( char& aCharacter ); // [17]

};

Class iVigenereStream is an object adapter for character file input streams. There is, however, one important characteristic of iVigenereStream that must be considered. Unlike standard character input file streams that ignore white space characters when performing formatted input by default, iVigenereStream must not skip white space characters. Hence, the underlying file stream must be processed in binary mode. In addition, we must access the characters of the underlying input file stream using ifstream’s get() method. This guarantees raw data access, which is required for the proper functioning of class iVigenereStream.

Class iVigenereStream does not define a default constructor. We always have to specify at least the scrambling mode aCipher and the keyword string aKeyword. The parameter aCipher expects a callable object. In this problem, we wish to decode a text input stream. Hence, we use the following lambda expression as parameter aCipher:

auto lCallable = []( Vigenere& aCipherProvider, char aCharacter )

{

return aCipherProvider.decode( aCharacter );

};

The lambda expression lCallable takes two arguments: a cipher provider and a character. It returns a decoded character as result.

The second argument to the constructor of iVigenereStream is aKeyword that we use to initialize the fCipherProvider member variable. (The cipher provider is a Vigenere object.)

The third constructor argument is a file name. If it is not nullptr, then the underlying fine stream must be opened.

File streams are value-based objects in C++. When these objects go out of scope, the corresponding destructor guarantees that the underlying file stream is properly closed.

The methods open() and close() have the expected semantics.

The method reset() has to restart an iVigenereStream stream. That is, this method resets the underlying cipher provider and positions the file pointer to the first character in the underlying file input stream. You can use the method seekstart() for this purpose.

The methods good(), is_open(), and eof() return the corresponding Boolean values from the underlying input file stream.

There is also a bool() method. This is a type conversion method that allows objects of type iVigenereStream to be used in a context where a Boolean value is expected. We use bool() to check if the underlying file input stream has reached end-of-file.

Finally, iVigenereStream provides formatted input for characters. This formatted input has to get a character from the underlying file input stream (note, raw input here). If we have not yet reached end-of-file, then the character must be processed by the cipher provider. That is, we call fCipher with the right arguments to obtain the result aCharacter.

You can test your implementation of iVigenereStream using the following test driver (enable #define P3 in main.cpp):

#include "iVigenereStream.h"

int runP3( string argv[2] )

{

iVigenereStream lInput( []( Vigenere& aCipherProvider, char aCharacter )

{

return aCipherProvider.decode( aCharacter );

} , argv[0], argv[1].c_str() );

if ( !lInput.good() )

{

cerr << "Cannot open input file: " << argv[1] << endl;

return 2;

}

cout << "Decoding \"" << argv[1] << "\" using \"" << argv[0] << "\"." << endl;

char lCharacter;

while ( lInput >> lCharacter )

{

cout << lCharacter;

}

lInput.close();

cout << "Completed." << endl;

return 0;

}

Running the test driver should produce the following output (Shakespeare’s Richard III). The file sample_3.txt must be in the “Working Directory”.

Decoding "sample_3.txt" using "Relations".

ACT I SCENE I

London. A Street.

Enter Gloucester.

Gloucester. Now is the winter of our discontent Made glorious summer by this sun of York;

And all the clouds that lour'd upon our house In the deep bosom of the ocean buried.

Now are our brows bound with victorious wreaths; Our bruised arms hung up for monuments;

Our stern alarums changed to merry meetings; Our dreadful marches to delightful measures.

Grim-visag'd war hath smooth'd his wrinkled front; And now, - instead of mounting barbed steeds,

To fright the souls of fearful adversaries, - He capers nimbly in a lady's chamber

To the lascivious pleasing of a lute.

But I, that am not shap'd for sportive tricks, Nor made to court an amorous looking-glass;

I, that am rudely stamp'd, and want love's majesty To strut before a wanton ambling nymph;

I, that am curtail'd of this fair proportion, Cheated of feature by dissembling nature, Deform'd, unfinish'd, sent before my time

Into this breathing world, scarce half made up, And that so lamely and unfashionable

That dogs bark at me, as I halt by them; Why, I, in this weak piping time of peace, Have no delight to pass away the time, Unless to see my shadow in the sun

And descant on mine own deformity:

And therefore, since I cannot prove a lover, To entertain these fair well-spoken days,

I am determined to prove a villain,

And hate the idle pleasures of these days. Plots have I laid, inductions dangerous, By drunken prophecies, libels, and dreams, To set my brother Clarence and the king

In deadly hate the one against the other: And if King Edward be as true and just

As I am subtle, false, and treacherous,

This day should Clarence closely be mew'd up, About a prophecy, which says, that G

Of Edward's heirs the murderer shall be.

Dive, thoughts, down to my soul: here Clarence comes.

Brother, good day: what means this armed guard That waits upon your Grace?

Completed.

vigenere.cpp

main.cpp

Hint
ComputerObject: In object-oriented programming (OOP), an object is an abstract data type which is created by a developer. It usually include the multiple properties and methods and could even contain several other objects. Also, in most of the programming languages, objects are known as the classes....

Know the process

Students succeed in their courses by connecting and communicating with
an expert until they receive help on their questions

1
img

Submit Question

Post project within your desired price and deadline.

2
img

Tutor Is Assigned

A quality expert with the ability to solve your project will be assigned.

3
img

Receive Help

Check order history for updates. An email as a notification will be sent.

img
Unable to find what you’re looking for?

Consult our trusted tutors.

Developed by Versioning Solutions.