XOR Checksum Question

Aug 25, 2011 at 11:10pm
Hi,

I am trying to implement an XOR Checksum algorithm, which takes in a binary file and performs the algorithm returning the checksum. This is what I have so far:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
int checksum(char filename[])
{
    ifstream infile(filename, ios::in);
    if (infile.fail())
    {
        cout << "Unable to open input file: " << filename << endl;
        return 0;
    }

    int checksum = 0;
    while(infile.good())
    {
        int x;
        infile.read((char*)&x, sizeof(int));
        
        if(infile.good())
        {
            checksum = checksum ^ x;
        }
    }

    infile.close();
    return checksum;
}


Do you see anything wrong with this algorithm? Is there a possibility that 2 slightly different files may return the same exact checksum value? This occurred for me. For example:

File #1
...
0x7b
...
0x2b
...

File #2
...
0x77
...
0x27
...


This happened to me. The 2 files only had 2 differences at these locations.

Thanks
Aug 25, 2011 at 11:19pm
Do you see anything wrong with this algorithm?


The only thing I see is that you assume the file will be of a size perfectly divisible by sizeof(int). If that's not the case then 'x' will be undefined giving you unreliable results. You should zero x:

 
int x = 0;


Is there a possibility that 2 slightly different files may return the same exact checksum value?


Yes. Especially with such a simple algorithm.
Aug 25, 2011 at 11:36pm
If you want to stick to your algorithm, you could at least increase its processing block size.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
struct DataBlock
{
    static const int block_size = 64;

    char data[block_size];

    DataBlock()
    {
        for (int i = 0; i < block_size; ++i) data[i] = 0;
    }

    void operator ^= (const DataBlock & other)
    {
        for (int i = 0; i < block_size; ++i)
            this->data[i] ^= other.data[i];
    }
};

DataBlock checksum(char filename[])
{
    DataBlock ret;

    ifstream infile(filename, ios::in);

    if (infile.fail())
    {
        cout << "Unable to open input file: "
             << filename << endl;

        return ret;
    }

    DataBlock cur_block;

    while(infile.good())
    {
        infile.read((char*)&cur_block, sizeof(DataBlock));

        if(infile.good()) ret ^= cur_block;
    }

    infile.close();

    return ret;
}
Last edited on Aug 26, 2011 at 7:56am
Topic archived. No new replies allowed.