Patrick B. answered 10/12/19
Math and computer tutor/teacher
using namespace std;
#include <iostream>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#define REVERSE_ALPHA ("ZYXWVUTSRQPONMLKJIHGFEDCBA")
#define ALPHABET ("ABCDEFGHIJKLMNOPQRSTUVWXYZ")
inline char AlphaIndex(int iIndex) { return( (char) (iIndex+65)); }
inline int IntIndex( char ch) { return( ch-65); }
class Alpha
{
private:
int iIndex;
char ch;
public:
Alpha ( int i, char c)
{
iIndex=i; ch=c;
}
Alpha()
{
iIndex=0; ch='?';
}
void SetIndex( int i) { iIndex=i; }
void SetChar( char c) { ch = c; }
int GetIndex() { return(iIndex); }
char GetChar() { return(ch); }
};
int AlphaCompareChar ( const void * x, const void * y)
{
Alpha * alpha1 = (Alpha *)x;
Alpha * alpha2 = (Alpha *)y;
return( alpha1->GetChar() - alpha2->GetChar( ));
}
int AlphaCompareIndex ( const void * x, const void * y)
{
Alpha * alpha1 = (Alpha *)x;
Alpha * alpha2 = (Alpha *)y;
return( alpha1->GetIndex() - alpha2->GetIndex( ));
}
void BuildAlphaTable( char * inbuff, Alpha * A )
{
int iIndex=0;
//for each character in the input buffer, assigns the array indices on
// first come first serve basis
int inputLen = strlen(inbuff);
for (int iLoop=0; iLoop<inputLen; iLoop++)
{
char ch = inbuff[iLoop];
ch = toupper(ch);
if (
(ch>='A') && (ch<='Z')
)
{
int jIndex = IntIndex(ch);
cout << " character " << ch << " is at index " << jIndex << endl;
//POSITIONS ARE 1-based !!!!
if (A[jIndex].GetIndex()==0)
{
A[jIndex].SetIndex(++iIndex);
cout << "character " << A[jIndex].GetChar() << " is given position " << iIndex << endl;
}
}
}
}
void GetCryptKey( Alpha * A, char * cryptKey)
{
for (int iLoop=0; iLoop<26; iLoop++)
{
cryptKey[iLoop]=A[iLoop].GetChar();
}
}
void Crypt ( char * key, bool cryptFlag, char * sourceFilename, char * destFilename)
{
FILE * infile;
FILE * outfile;
char ch;
infile = fopen(sourceFilename,"r");
outfile = fopen(destFilename,"w");
while ((fscanf(infile,"%c",&ch) != EOF))
{
if ( isalpha(ch))
{
ch = toupper(ch);
if (cryptFlag)
{
int iIndex = IntIndex(ch);
fprintf(outfile,"%c",key[iIndex]);
}
else
{
int iLoop=0;
for (iLoop=0; iLoop<26; iLoop++)
{
if (key[iLoop]==ch)
{
break;
}
}
fprintf(outfile,"%c",ALPHABET[iLoop]);
}
}
else
{
fprintf(outfile,"%c",ch);
}
}
fclose(infile);
fclose(outfile);
}
int Go(bool cryptFlag, char * Key, char * inputFilename, char * outputFilename)
{
Alpha alpha[26];
char cryptKey[26];
char key[255];
char inbuff[300];
cout << "Key = " << Key << endl;
strcpy(key,Key);
memset(inbuff,0,300);
sprintf(inbuff,"%s%s",key,REVERSE_ALPHA);
//populates the array with 'A','B',...'Z' and index zer0
for (int iLoop=0; iLoop<26; iLoop++)
{
alpha[iLoop].SetIndex(0);
alpha[iLoop].SetChar(AlphaIndex(iLoop));
}
BuildAlphaTable(inbuff,alpha);
qsort(alpha,26,sizeof(Alpha),AlphaCompareIndex);
GetCryptKey(alpha,cryptKey);
for (int iLoop=0; iLoop<26; iLoop++)
{
cout << " alpha char = " << alpha[iLoop].GetChar() << " : index = " << alpha[iLoop].GetIndex() << endl;
}
cout << " the crypt key is "<< cryptKey << endl;
Crypt( cryptKey,cryptFlag,inputFilename,outputFilename );
}
bool ProcessArgs (int argc, char * argv[] )
{
bool bReturn1;
bool bReturn2;
/***********************
argv[1] must be either -d or -e
argv[2] must he -kKEYSTRING which contains all capital letter
argv[3] and argv[4] are filenames
******************/
if (
(strcmp(argv[1],"-e")==0) ||
(strcmp(argv[1],"-E")==0) ||
(strcmp(argv[1],"-d")==0) ||
(strcmp(argv[1],"-D")==0)
)
{
argv[1][1]=toupper(argv[1][1]);
bReturn1=true;
}
else
{
bReturn1=false;
}
if (
((argv[2][0])=='-') &&
(
((argv[2][1])=='K') || ((argv[2][1])=='k')
)
)
{
bReturn2=true;
}
else
{
bReturn2=false;
}
return (bReturn1 && bReturn2);
}
int main( int argc, char * argv[])
{
if (argc==5)
{
if (ProcessArgs(argc, argv))
{
Go((argv[1][1]=='E'),&argv[2][2],argv[3],argv[4] );
}
else
{
cout << " crypt -d -kKEY inputfilename outputfilename " << endl;
cout << " crypt -e -kKEY inputfilename outputfilename " << endl;
}
}
else
{
cout << " crypt -d -kKEY inputfilename outputfilename " << endl;
cout << " crypt -e -kKEY inputfilename outputfilename " << endl;
}
}