2's Compliment Checksum

Dec 14, 2010 at 1:29pm
Hi guys. I am trying to calculate the 2's compliment checksum of an array of characters using the following code:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
unsigned long long end = 512;
unsigned long long checksum = 0;
unsigned short int twoByteLoingCheckSum = 0;

// Add all of the bytes in the array together
for(unsigned long long i = 0; i < end; i++){
	checksum = checksum + (unsigned int)((unsigned char)buffer[i]);
}

// invert the bits for the first 2 bytes
for(int t = 32768; t > 0; t = t / 2){
	if(checksum & t) 	checksum = checksum - t;
	else 			checksum = checksum + t;
}

// Add 1
checksum = checksum + 1;

// Print only the first two (LSBs) bytes of the checksum
unsigned short int twoByteLongCheckSum = (unsigned short int)checksum;
printf("\n\t2's Compliment Checksum: %04X", twoByteLongCheckSum);


Can anyone see something wrong with it? because it is not calculating the expected value for me!

thanks in advance :)
Last edited on Dec 14, 2010 at 1:30pm
Dec 14, 2010 at 3:52pm
2's compliment is a way to handle signed numbers. Since you're printing as unsigned, there's no point. You could just do this:

1
2
3
4
for(i = 0; i < end; ++i)
  checksum += buffer[i];

printf("2's compliment checksum:  %04X", checksum & 0xFFFF );



Furthermore, even if you print as signed, the beauty of 2's compliment is that it works the same with both signed and unsigned numbers, so you don't have to worry about details.

If you want a 16 bit signed number, just make one:

1
2
3
4
5
6
7
8
short checksum = 0;  // 16-bit signed

for(i = 0; i < end; ++i)
  checksum += buffer[i];  // maybe cast buffer[i] to unsigned/signed char depending on how
                    // you're supposed to interpret that data

// print as a signed, 16-bit, 2's compliment checksum:
printf("%d", checksum);
Last edited on Dec 14, 2010 at 3:53pm
Dec 15, 2010 at 11:17am
Thanks that was very helpful. I think I was trying over complicate things :)

Also for anyone reaching this page via google, it might be useful to know that if your checksum is not what you expect it to be, try calculating using blocks of 2 bytes from your data set, rather than 1. Took me a while to figure that one out ^_^

Thanks again Disch.
Topic archived. No new replies allowed.