Background: A common way to ensure that binary data has not been tampered with o
ID: 3621634 • Letter: B
Question
Background:
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. One of the earliest and simplest checksum algorithms is the Modular Sum checksum algorithm. For an 8 bit checksum of this type, add all the characters of the input file into an unsigned integer variable. Then compute the two’s complement of the sum and add one to it. Append this value to the file.
When the checksum is now computed on the file, it will have a value of zero if the file has not been altered.
You may wonder how characters such as ‘a’, ‘b’, ‘c’, etc. can be added. The answer is that the ASCII representation of the characters are added, which are integers. The computer cannot store letters but only numbers, so the ASCII table maps every character into a number.
The two’s complement can be computed by flipping all the bits of the number and then adding one. Bits can be flipped using the exclusive OR operator. In C/C++, this is the caret operator , ^. Before adding one, truncate all but the lowest 8 bits of the 4 byte sum variable by ANDing with a mask like this:
sum = sum & 0x000000FF
The result is stored in another byte which is appended to the file.
When that file is read by another party, the same checksum is run over the data, including the last byte. If the resulting checksum is not all zeros, the data has been compromised. Note that when verifying a checksum, nothing is appended to the file.
Of course, using an 8 bit checksum of this type is not very reliable, but it is indicative of how most checksums and hashes are used. Using 16 bits or more increases the reliability drastically.
Your assignment is to write a C++ program which will automatically compute the checksum on a specified data file, and then append the checksum to the file. Your program should also verify that a specified file has not been compromised by running the checksum over it and verifying that it is zero.
Sample Dialog:
Note: In the example below, the user’s input is in RED BOLD. The program output is not.
Please select:
A) Add checksum to specified file
B) Verify integrity of specified file
Q) Quit
a
Specify the file path: C: emp mpFile.txt
File checksum = 138
Please select:
A) Add checksum to specified file
B) Verify integrity of specified file
Q) Quit
b
Specify the file path: C: emp mpFile.txt
File checksum = 0
The file integrity check has passed successfully.
Please select:
A) Add checksum to specified file
B) Verify integrity of specified file
Q) Quit
b
Specify the file path: c: emp mpFile.txt
File checksum = 174
The file integrity check has failed - the file has been compromised!
Please select:
A) Add checksum to specified file
B) Verify integrity of specified file
Q) Quit
a
Specify the file path: r: emp mpFile.txt
The file "r: emp mpFile.txt" could not be found or opened!
Please select:
A) Add checksum to specified file
B) Verify integrity of specified file
Q) Quit
Please upload the source code. Thanks
Explanation / Answer
please rate - thanks
#include <iostream>
#include <fstream>
using namespace std;
char menu();
void create();
unsigned int calculate(char&,char[]);
void verify();
int main()
{char choice;
choice=menu();
while(choice!='Q')
{switch(choice)
{
case 'A': create();
break;
case 'B': verify();
break;
default: cout<<"invalid input ";
}
choice=menu();
}
return 0;
}
char menu()
{char choice;
cout<<"Please select: ";
cout<<"A) Add checksum to specified file ";
cout<<"B) Verify integrity of specified file ";
cout<<"Q) Quit ";
cin>>choice;
return toupper(choice);
}
unsigned int calculate(char& last, char filename[])
{char ch;
ifstream input;
int checksum=0;
cout<<"Specify the file path: ";
cin>>filename;
input.open(filename); //open file
if(input.fail()) //is it ok?
{ cout<<"The file "<<filename<<" could not be found or opened! ";
input.clear();
return 1;
}
input.get(ch);
while(input)
{checksum+=ch;
if(ch!=' ')
last=ch;
input.get(ch);
}
input.close();
return checksum;
}
void create()
{unsigned int checksum=0;
int check;
char ch,filename[30];
checksum=calculate(ch,filename);
ofstream out;
out.open(filename,fstream::app);
checksum=~checksum; //~ flips the bits
checksum=checksum&0x000000FF;
check=++checksum;
cout<<"File checksum = "<<check<<endl;
out<<(char)check<<endl;
out.close();
out.clear();
}
void verify()
{unsigned int checksum;
char ch,filename[30];
checksum=calculate(ch,filename);
checksum-=' '; //don't count the last enter after the checksum
checksum=~checksum;
++checksum;
checksum=checksum&0x000000FF;
cout<<"File checksum = "<<checksum<<endl;
if(checksum==0)
cout<<"The file integrity check has passed successfully. ";
else
cout<<"The file integrity check has failed - the file has been compromised! ";
}
Related Questions
drjack9650@gmail.com
Navigate
Integrity-first tutoring: explanations and feedback only — we do not complete graded work. Learn more.