CS249-Projects/PA01-0906/EncryptionUtility.c
cdez 5777809d47 Refined PA01 - File_IO
+- EncryptionUtility.c
+- outRelease (precompiled for UNIX style systems)
NOTE: Use Make to compile for Windows systems
2023-09-05 23:09:01 -07:00

471 lines
15 KiB
C

#include "EncryptionUtility.h"
// local constants
const char ASTERISK = '*';
const int UNPRINTABLE_CHAR_VALUE = 127; // delete key, unprintable
const int NUM_ALPHABET_LETTERS = 52;
const double SQRT_PRECISION = 0.000001;
const char ALPHABET[] = "AaBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQqRrSsTtUuVvWwXxYyZz";
// functions
/*
Name: clearArrayType
Process: Clears data type array rows, then data type array, then data type
Function input/parameters: pointer to square array type (SquareArrayType *)
Function output/parameters: none
Function output/returned: NULL (SquareArrayType *)
Device input/---: none
Device output/---: none
Dependencies: as needed
*/
SquareArrayType *clearArrayType( SquareArrayType *data )
{
int rowIndex;
for( rowIndex = 0; rowIndex < data->sideSize; rowIndex++ )
{
free( data->array[ rowIndex ] );
}
free( data->array );
free( data );
return NULL;
}
/*
Name: createArrayType
Process: Creates square array type, creates side size array rows,
creates side size array columns,
sets each element to ASTERISK constant,
sets side size to parameter value
Function input/parameters: array side size (int)
Function output/parameters: none
Function output/returned: pointer to new square array type (SquareArrayType *)
Device input/---: none
Device output/---: none
Dependencies: as needed
*/
SquareArrayType *createArrayType( int sideSize )
{
int rowIndex, colIndex;
SquareArrayType *newData;
newData = (SquareArrayType *)malloc( sizeof( SquareArrayType ) );
newData->sideSize = sideSize;
newData->array = (int **)malloc( sideSize * sizeof( int * ) );
for( rowIndex = 0; rowIndex < sideSize; rowIndex++ )
{
newData->array[ rowIndex ] = (int *)malloc( sideSize * sizeof( int ) );
for( colIndex = 0; colIndex < sideSize; colIndex++ )
{
newData->array[ rowIndex ][ colIndex ] = (int)ASTERISK;
}
}
return newData;
}
/*
Name: decryptData
Process: Decrypts given data array, provides result as string
Function input/parameters: pointer to square array type (SquareArrayType *)
Function output/parameters: decrypted string (char *)
Function output/returned: none
Device input/---: none
Device output/---: none
Dependencies: as needed
*/
void decryptData( char *decryptStr, SquareArrayType *data )
{
// opposite the encrypt data.
// extract the size data from the array
int arraySizeData = data->sideSize;
// iterate through the array
int oneDimensionIndex;
int twoDimensionIndex;
int differenceIndex;
int currentCharacter = 0;
int stringComplete = 0;
for(oneDimensionIndex = arraySizeData * 2; oneDimensionIndex >= 0;
oneDimensionIndex--)
{
// does one dimensional indices
for(twoDimensionIndex = oneDimensionIndex; twoDimensionIndex >= 0;
twoDimensionIndex--)
{
// does two dimensional indices
differenceIndex = oneDimensionIndex - twoDimensionIndex;
if(differenceIndex < arraySizeData && twoDimensionIndex < arraySizeData)
{
// second dimension to move through array
if(stringComplete == 0)
{
if(data->array[twoDimensionIndex][differenceIndex] ==
UNPRINTABLE_CHAR_VALUE)
{
// check for the unprintable character
decryptStr[currentCharacter] = NULL_CHAR;
stringComplete = 1;
}
else
{
// put the character into the string.
decryptStr[currentCharacter] =
data->array[twoDimensionIndex][differenceIndex];
currentCharacter = currentCharacter + 1;
}
}
}
}
}
// no return.
}
/*
Name: displayArray
Process: Displays 2 dimensional array data either as characters or integers
depending on control code
Function input/parameters: square data array (const SquareArrayType)
Function output/parameters: none
Function output/returned: none
Device input/---: none
Device output/monitor: data displayed as specified
Dependencies: as needed
Notes: Does not handle empty square data type condition
*/
void displayArray( const SquareArrayType data, ControlCode ctrlCode )
{
int arraySize = data.sideSize;
int oneDimensionIndex = 0, twoDimensionIndex = 0;
// check the control code, branch to the respective path.
// iterate through the array, one character at a time.
// get the side size from the array,
// iterate that number of times, then output a new line.
if(ctrlCode == DISPLAY_CHARS)
{
for(oneDimensionIndex = 0; oneDimensionIndex < arraySize;
oneDimensionIndex++)
{
for(twoDimensionIndex = 0; twoDimensionIndex < arraySize;
twoDimensionIndex++)
{
printCharacter((char)data.array[oneDimensionIndex][twoDimensionIndex]);
printCharacter(SPACE);
}
printEndline();
}
}
else
{
for(oneDimensionIndex = 0; oneDimensionIndex < arraySize;
oneDimensionIndex++)
{
for(twoDimensionIndex = 0; twoDimensionIndex < arraySize;
twoDimensionIndex++)
{
printInteger((int)data.array[oneDimensionIndex][twoDimensionIndex]);
printCharacter(SPACE);
}
printEndline();
}
}
// no return.
}
/*
Name: downloadData
Process: downloads given data array along with side size header,
does not download empty array (i.e., if side size is zero)
Function input/parameters: file name (const char *),
square data array (const SquareArrayType)
Function output/parameters: none
Function output/returned: none
Device input/---: none
Device output/HD: data output to file as specified
Dependencies: as needed, File_Output_Utility tools
*/
void downloadData( const char *fileName, const SquareArrayType data )
{
bool fileOpenCheck;
int oneDimensionIndex, twoDimensionIndex;
int currentData;
int checkDigits, tempDigits;
// open file.
fileOpenCheck = openOutputFile(fileName);
// write file.
if(fileOpenCheck)
{
// write the size of the array as the first character.
writeIntegerToFile(data.sideSize);
// write a new line
writeEndlineToFile();
// iterate through array outputting each integer.
for(oneDimensionIndex = 0; oneDimensionIndex < data.sideSize;
oneDimensionIndex++)
{
//
for(twoDimensionIndex = 0; twoDimensionIndex < data.sideSize;
twoDimensionIndex++)
{
//
currentData = data.array[oneDimensionIndex][twoDimensionIndex];
// check to see if the integer is two digits, if it is, add a 0 before.
checkDigits = 1;
tempDigits = currentData;
while(tempDigits > 9)
{
tempDigits = tempDigits / 10;
checkDigits = checkDigits + 1;
}
if(checkDigits == 2)
{
writeCharacterToFile(ZERO_CHAR);
writeIntegerToFile(currentData);
}
else
{
writeIntegerToFile(currentData);
}
writeCharacterToFile(SPACE);
}
writeEndlineToFile();
}
}
else
{
// if the file doesn't open, notify the user.
printf("\nThe file either doesn't exist,"
"or you do not have permission to access it.\n");
}
// close file.
closeOutputFile();
// no return.
}
/*
Name: encryptData
Process: finds side size for given string,
creates new array type,
encrypts data to 2D array using provided strategy
Function input/parameters: string to be encrypted (const char *)
Function output/parameters: none
Function output/returned: pointer to new array type (SquareArrayType *)
Device input/---: none
Device output/---: none
Dependencies: as needed, including findStringLength, findSquareRoot,
getRandomLetterValue (library utilities may not be used)
*/
SquareArrayType *encryptData( const char *toEncrypt )
{
// get length of string (store in variable)
int stringLen = findStringLength(toEncrypt);
// create the array (get the square root, add one,
// then call the function to make a square array.)
int stringLenRoot = findSquareRoot(stringLen) + 1;
SquareArrayType *encryptedData = createArrayType(stringLenRoot);
// iterate through the array (backwards, diagonally)
int oneDimensionIndex;
int twoDimensionIndex;
int differenceIndex;
int currentCharacter = 0;
for(oneDimensionIndex = stringLenRoot * 2; oneDimensionIndex >= 0;
oneDimensionIndex--)
{
// does one dimensional indices
for(twoDimensionIndex = oneDimensionIndex; twoDimensionIndex >= 0;
twoDimensionIndex--)
{
// does two dimensional indices
differenceIndex = oneDimensionIndex - twoDimensionIndex;
if(differenceIndex < stringLenRoot && twoDimensionIndex < stringLenRoot)
{
// second dimension to move through array
if(currentCharacter >= stringLen)
{
if(currentCharacter == stringLen)
{
// if the null character is there,
// replace with the Unprintable, set flag to one.
encryptedData->array[twoDimensionIndex][differenceIndex] =
UNPRINTABLE_CHAR_VALUE;
}
else
{
// if not the null, put random data into array
encryptedData->array[twoDimensionIndex][differenceIndex] =
getRandomLetterValue();
}
}
else
{
// otherwise, continue putting the data into the 2d array.
encryptedData->array[twoDimensionIndex][differenceIndex] =
toEncrypt[currentCharacter];
}
currentCharacter = currentCharacter + 1;
}
}
}
// once null character is reached, put the 'unprintable character'
// then random data afterward.
// returns a Square Array.
return encryptedData;
}
/*
Name: findSquareRoot
Process: finds estimated square root of integer value
to specified SQRT_PRECISION using divide and conquer strategy
Function input/parameters: value to be square rooted (int)
Function output/parameters: none
Function output/returned: estimated square root as specified (double)
Device input/---: none
Device output/---: none
Dependencies: as needed (library utilities may not be used)
*/
double findSquareRoot( int value )
{
// declare, define variables as needed
// set lower value to zero, upper value to the original value
double lowerValue = 0, upperValue = value;
// set middle value between the lower and upper values
double middleValue = ( lowerValue + upperValue ) / 2.0;
// calculate the initial temporary value
double tempResult = middleValue * middleValue;
// loop while absolute difference between test value and original value
// is greater than the specified precision
// function: abs, from stdlib.h
while( abs( tempResult - value ) > SQRT_PRECISION )
{
// test for the temporary result to be greater than the original value
if( tempResult > value )
{
// set the upper value to the middle value
upperValue = middleValue;
}
// otherwise, assume the temporary result is less than the original value
else
{
// set the lower value to the middle value
lowerValue = middleValue;
}
// end test
// recalculate middle value
middleValue = ( lowerValue + upperValue ) / 2.0;
// recalculate the temporary result
tempResult = middleValue * middleValue;
}
// end loop
// return middle value
return middleValue;
}
/*
Name: findStringLength
Process: finds length of given c-style string
Function input/parameters: string for finding length (const char *)
Function output/parameters: none
Function output/returned: length of string (int)
Device input/---: none
Device output/---: none
Dependencies: as needed (library utilities may not be used)
*/
int findStringLength( const char *str )
{
// needs to iterate through the 'string' checking if the character is NULL.
// if character not null, add one to count.
int index = 0;
while(str[index] != NULL_CHAR)
{
index = index + 1;
}
// returns an integer count of the number of characters.
return index;
}
/*
Name: getRandomLetterValue
Process: generates integer value of randomly found upper or lower case letter
in ALPHABET array
Function input/parameters: none
Function output/parameters: none
Function output/returned: integer value of random letter, as specified (int)
Device input/---: none
Device output/---: none
Dependencies: as needed, including rand
*/
int getRandomLetterValue()
{
int currentRand = 0;
// generate random number between 1 and 52
currentRand = rand() % (NUM_ALPHABET_LETTERS + 1) + 1;
// then get the integer that character corresponds to and return it.
int letterInt = (int)ALPHABET[currentRand];
// returns an integer.
return letterInt;
}
/*
Name: uploadData
Process: creates square array type, uploads data from text file,
gets side size from header, then loads array values
Function input/parameters: file name (const char *)
Function output/parameters: none
Function output/returned: pointer to square array type (SquareArrayType *)
Device input/HD: data input from text file as specified
Device output/---: none
Dependencies: as needed, File_Input_Utility tools
*/
SquareArrayType *uploadData( const char *fileName )
{
bool fileOpenCheck;
int arraySizeFile;
int oneDimensionIndex, twoDimensionIndex;
SquareArrayType *readArray;
// open file.
fileOpenCheck = openInputFile(fileName);
// read file.
if(fileOpenCheck)
{
// read the size of the array as the first character.
arraySizeFile = readIntegerFromFile();
// create the square array
readArray = createArrayType(arraySizeFile);
// read integer, iterate through array inputting each integer.
for(oneDimensionIndex = 0; oneDimensionIndex < arraySizeFile;
oneDimensionIndex++)
{
for(twoDimensionIndex = 0; twoDimensionIndex < arraySizeFile;
twoDimensionIndex++)
{
// input data into array from file
readArray->array[oneDimensionIndex][twoDimensionIndex] =
readIntegerFromFile();
}
}
}
else
{
// if the file doesn't open, notify the user.
printf("The file either doesn't exist,"
"or you do not have permission to access it.\n");
}
// close file.
closeInputFile();
// returns a Square Array.
return readArray;
}