Academic Integrity: tutoring, explanations, and feedback — we don’t complete graded work or submit on a student’s behalf.

(Please answer using C++ language) a.out keyfilename < clearfile > cryptfile Cre

ID: 3771038 • Letter: #

Question

 (Please answer using C++ language)  a.out keyfilename < clearfile > cryptfile  Create a "High Security" product often hawked by scammers.  Write a program which functions as a filter (input from keyboard, output to screen) after opening a key file OR reading the key phrase from the command line.  ========================== key is a file: a.out keyfile < inputfile  > outputfile  key is a CLI password: a.out secret < inputfile  > outputfile  key is a CLI phrase: a.out this is a key phrase fnord rebus fnord fnord < inputfile > outputfile ==========================  When pgm reaches the end of keyfile, password, or constructed passphrase, it rewinds and continues.  When it reaches the end of inputfile, the program ends.  For each keyfile char and input char it reads, they are exclusive or-ed  together, and the resulting character is written on the outputfile.  Base your design on the watermpump skeleton, and keep a constant watch on both key and input files as it runs:   int c = fgetc(inputfile) ; while (c != EOF) {         if (feof(keyfile)) rewind(keyfile) ;         .         . } // while  ----------------------------              After processing, check to see that the number of bytes         in the output stream is the same as the number of bytes         in the input stream.  If not, you have an error.          The program should exactly decrypt what it incrypts:          a.out keyfile < clear > crypt         a.out keyfile < crypt  (output should exactly match contents of clear)  The program should try to open the argv[1 to n] parm as a keyfile and read its contents into a string or char array. If there is no such file, it will use the argv[1-] parm as the key.  In either case, the individual key characters may be accessed one at a time.  You may assume that the key or keyfile will not be too long to fit into a C++ string object. 

Explanation / Answer

program : #include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
using namespace std;
#define POLYNOMIAL 0x04C11DB7L
#define M 32   
#define K 4   
typedef unsigned short int word16;
typedef unsigned int word32;
static word32 CrcTable[256];   
char BFilter[M / 8];
word32 NumBytes;   
void gen_crc_table(void);
word32 update_crc(word32 crc_accum, char *data_ptr, word32 data_size);
void mapBloom(word32 hash);
int testBloom(word32 hash);
int main()
{
FILE *fp1;
FILE *fp2;
char inFile1[256];
char inFile2[256];
char inString[1024];
word32 crc32;
int retCode;
word32 i;
cout<<"------------------------------------------ "<<endl;
cout<<"- Program to implement a general Bloom filter ";
cout<<"------------------------------------------ "<<endl;
NumBytes = M / 8;
if ((M % 8) != 0)
{
cout<<"*** ERROR - M value must be divisible by 8 ";
exit(1);
}
for (i = 0; i < NumBytes; i++)
BFilter[i] = 0x00;
gen_crc_table();
cout<<"File name of input list to add to filter ===========> ";
cin>>inFile1;
fp1 = fopen(inFile1, "r");
if (fp1 == NULL)
{
cout<<"ERROR in opening input file #1 ("<<inFile1<<") *** ";
exit(1);
}
cout<<"File name of input list to check for match =========> ";
cin>>inFile2;
fp2 = fopen(inFile2, "r");
if (fp2 == NULL)
{
cout<<"ERROR in opening input file #1 ("<<inFile2<<") *** ";
exit(1);
}
while (1)
{
fgets(inString, 1024, fp1);
if (feof(fp1))
break;
for (i = 0; i < K; i++)
{
crc32 = update_crc(i, inString, strlen(inString));
mapBloom(crc32);
}
}
fclose(fp1);
cout<<"-------------------------------------------------------- ";
cout<<"Bloom filter is (M = "<<M<<" bits and K = "<<K<<" mappings)... ";
for (i = 0; i < NumBytes; i++)
printf("%2d", i);
cout<<endl;
for (i = 0; i < NumBytes; i++)
printf("%02X", BFilter[i]);
cout<<endl;
cout<<"----------------------------------------------------- ";
cout<<"Matching strings are... ";
while(1)
{
fgets(inString, 1024, fp2);
if (feof(fp2))
break;
for (i = 0; i < K; i++)
{
crc32 = update_crc(i, inString, strlen(inString));
retCode = testBloom(crc32);
if (retCode == 0)
   break;
}
if (retCode == 1)
cout<<inString;
}
fclose(fp2);
}
void gen_crc_table(void)
{
register word32 crc_accum;
register word16 i, j;
for (i = 0; i < 256; i++)
{
crc_accum = ((word32) i << 24);
for (j = 0; j < 8; j++)
{
if (crc_accum & 0x80000000L)
crc_accum = (crc_accum << 1) ^ POLYNOMIAL;
else
crc_accum = (crc_accum << 1);
}
CrcTable[i] = crc_accum;
}
}
word32 update_crc(word32 crc_accum, char *data_blk_ptr, word32 data_blk_size)
{
register word32 i, j;
for (j = 0; j < data_blk_size; j++)
{
i = ((int) (crc_accum >> 24) ^ *data_blk_ptr++) & 0xFF;
crc_accum = (crc_accum << 8) ^ CrcTable[i];
}
crc_accum = ~crc_accum;
return crc_accum;
}
void mapBloom(word32 hash)
{
int tempInt;
int bitNum;
int byteNum;
unsigned char mapBit;
tempInt = hash % M;
byteNum = tempInt / 8;
bitNum = tempInt % 8;
mapBit = 0x80;
mapBit = mapBit >> bitNum;
BFilter[byteNum] = BFilter[byteNum] | mapBit;
}
int testBloom(word32 hash)
{
int tempInt;
int bitNum;
int byteNum;
unsigned char testBit;
int retCode;
tempInt = hash % M;
byteNum = tempInt / 8;
bitNum = tempInt % 8;
testBit = 0x80;
testBit = testBit >> bitNum;
if (BFilter[byteNum] & testBit)
retCode = 1;
else
retCode = 0;
return retCode;
}