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

A common way to ensure that binary data has not been tampered with or has not be

ID: 3762914 • Letter: A

Question

A common way to ensure that binary data has not been tampered with or has not been corrupted by some event (transport, sending, etc.) is to test its “integrity”. This is done by running some hash or checksum algorithm on the binary data before the event and again after the event. If the results are not the same it can be concluded that the integrity of the data has been compromised (changed).

There are many checksum and hash algorithms that have been used over the years. They all generate some numeric value of fixed size based on examination of the binary data. For simplicity, we will not use a real checksum algorithm but instead just use a regular 32 bit sum. That is, we will add the ASCII values of each character of the input file.

You may wonder how characters such as ‘a’, ‘b’, ‘c’, etc. can be added. The key is remembering that computers cannot store letters but only numbers, and that the ASCII table maps every character into a number. The ASCII representations of all the characters are added together.

When that file is read, the same checksum is run over the same file data. If the resulting checksum is not the same as the previously computed checksum, the data has been compromised (changed).

Your assignment is to write a C++ program which will automatically compute the checksum on a specified data file, and then store that checksum in an unsigned integer array. The program must also store the file name in another, parallel array. You can use these declarations in your program:

const int SUM_ARR_SZ = 100;

unsigned int checkSums[SUM_ARR_SZ];

string fileNames[SUM_ARR_SZ];

This gives your program the flexibility to run checksums on several files (up to 100) and remember which sums go with which files.

Your program should then be able to verify that a specified file has not been compromised by running the checksum over it and verifying that the checksum is what it was previously.

Your program *must* read the file into a char array. Make the array size 100000 chars so that it is large enough for our file. After the file is stored in the array, your program must loop through the array to compute the checksum using the algorithm described above (simple sum).

Since this is essentially an operation on a binary file (even though text may be stored in the file), open the file in binary mode to prevent the system from performing any interpretation on the data like this:

inFile.open(filePath.c_str(), ios::binary);

To get the file size, use the seekg and tellg operators like this:

inFile.seekg(0, ios_base::end);

int fileLen = inFile.tellg();

inFile.seekg(0, ios_base::beg);

The first line moves the file cursor to the end of the file. The second line reads the byte position at that current location. The third statement moves the file cursor back to the beginning of the file so the data can be read from the beginning.

After that, you can read the entire file contents into your char array in one statement like this:

inFile.read(charArr, fileLen);

Then the file must be closed:

inFile.close();

The following line seems to be required to put the file back to a state where it can be opened again it (otherwise, some compilers, like mine, will not allow the file to be reopened):

inFile.clear(std::ios_base::goodbit);

For comparing file names, use the strcmp() built in function.

High level pseudocode for determining the checksum may look something like this:

Open the specified file in binary mode

Save the file name in the fileNames array.

Determine the file size using seekg and tellg

Read the file contents into the character array in one statement

Close the file

Loop through the array, one character at a time and accumulate the sum of each byte

Store the sum into the checkSums array.

Sample Dialog:

Note: In the example below, the user’s input is in RED BOLD. The program output is not. Also, your code should allow menu entry input in a case insensitive manner.

Please select:

A) Compute checksum of specified file

B) Verify integrity of specified file

Q) Quit

a

Specify the file path: c: emp mp1

File checksum = 1530

Please select:

A) Compute checksum of specified file

B) Verify integrity of specified file

Q) Quit

a

Specify the file path: c: emp mp2

File checksum = 29430

Please select:

A) Compute checksum of specified file

B) Verify integrity of specified file

Q) Quit

b

Specify the file path: c: emp mp1

File checksum = 1530

The file integrity check has passed successfully (checksum = 1530).

Please select:

A) Compute checksum of specified file

B) Verify integrity of specified file

Q) Quit

b

Specify the file path: c: emp mp1

File checksum = 1597

The file integrity check has failed (previous checksum = 1530, new checksum = 1597)

Please select:

A) Compute checksum of specified file

B) Verify integrity of specified file

Q) Quit

b

Specify the file path: c: emp mp3

File checksum = 5596

The checksum has not been computed on the file: c: emp mp3

Please select:

A) Compute checksum of specified file

B) Verify integrity of specified file

Q) Quit

here is what i have so far. I dont really understand why it isnt working. My teacher is not replying to any of my requests for help so im really lost here. I'm getting HUGE numbers for the check sum.

using namespace std;
// Declare Variables
char reply;
string filePath;
string calculate_checksum(filePath);

int checksum;
int main()
{
   const int SUM_ARR_SZ = 100;
   unsigned int checkSums[SUM_ARR_SZ];
   string fileNames[SUM_ARR_SZ];
   char charArr[100000];
   ifstream inFile;
   //inFile.open(filePath.c_str(), ios::binary);
   inFile.seekg(0, ios_base::end);
   int fileLen = inFile.tellg();
   inFile.seekg(0, ios_base::beg);

   inFile.read(charArr, fileLen);


   inFile.close();

   inFile.clear(std::ios_base::goodbit);

   do
   {
       cout << "Please select: " << endl;
       cout << "A) Compute checksum of specified file " << endl;
       cout << "B) Verify integrity of specified file " << endl;
       cout << "Q) Quit " << endl;
       cin >> reply;
       switch (reply)
       {
       case'A':
       case'a':
           cout << "Specify the file path: ";
           cin >> filePath;
           cout << "File checksum = " << checkSums[0] << endl;
           break;
       case'B':
       case'b':
           cout << "Specify the file path: ";
           cin >> filePath;

       if (checkSums[0] == checkSums[0])
           {
               cout << "The file integrity check has passed successfully (checksum = " << checkSums[0] << endl;

           }

       else
           {
               cout << "The file integrity check has failed (previous checksum = " << checkSums[0] << ", new checksums = " << checkSums[0] << ") " << endl;
           }

       break;
       case'Q':
       case'q':
           break;
       default:
           cout << "Invalid Input." << endl;
           break;

       }
   } while (reply != 'Q' && reply != 'q');
   system("pause");
   return 0;

}

Explanation / Answer


#include <iostream> #include <fstream> #include <string> #include <iomanip> using namespace std; // Declare Variables char reply; string filePath; int main() { const int SUM_ARR_SZ = 100; unsigned int checkSums[SUM_ARR_SZ]; string fileNames[SUM_ARR_SZ]; ifstream inFile; cout << "Please select: " << endl; cout << "A) Compute checksum of specified file " << endl; cout << "B) Verify integrity of specified file " << endl; cout << "Q) Quit " << endl; cin >> reply; switch (reply) { case'A': case'a': cout << "Specify the file path: " << endl; cin >> filePath; break; case'B': case'b': cout << "Specify the file path: " << endl; cin >> filePath; break; case'Q': case'q': break; default: cout << "Invalid Input." << endl; } inFile.open(filePath.c_str(), ios::binary); inFile.seekg(0, ios_base::end); int fileLen = inFile.tellg(); inFile.seekg(0, ios_base::beg); cout << "File checksum = " << checkSums << endl; inFile.close(); inFile.clear(std::ios_base::goodbit); system("pause"); return 0; }

Hire Me For All Your Tutoring Needs
Integrity-first tutoring: clear explanations, guidance, and feedback.
Drop an Email at
drjack9650@gmail.com
Chat Now And Get Quote