Checksum calculation - two’s complement sum of all bytes

29,331

Solution 1

You miscopied the example message from the pdf you linked. The second parameter length is 9 bytes, but you used 0x08 in your code.

The document incorrectly states "8 bytes" in the third column when there are really 9 bytes in the parameter. The second column correctly states "00001001".

In other words, your test message should be:

{0x80,0x15,0x1,0x8,0x30,0x33,0x31,0x35,0x31,0x30,0x33,0x30, // param1
 0x2,0x9,0x30,0x33,0x35,0x31,0x2d,0x33,0x32,0x31,0x30,0xe}  // param2
     ^^^

With the correct message array, ret == true when I try your program.

Solution 2

Agree with the comment: looks like the checksum is wrong. Where in the .PDF is this data?

Some general tips:

Use an unsigned type as the accumulator; that gives you well-defined behavior on overflow, and you'll need that for longer messages. Similarly, if you store the result in a char variable, make it unsigned char.

But you don't need to store it; just do the math with an unsigned type, complement the result, add 1, and mask off the high bits so that you get an 8-bit result.

Also, there's a trick here, if you're on hardware that uses twos-complement arithmetic: just add all of the values, including the checksum, then mask off the high bits; the result will be 0 if the input was correct.

Share:
29,331
Angus Comber
Author by

Angus Comber

Updated on September 03, 2020

Comments

  • Angus Comber
    Angus Comber over 3 years

    I have instructions on creating a checksum of a message described like this:

    The checksum consists of a single byte equal to the two’s complement sum of all bytes starting from the “message type” word up to the end of the message block (excluding the transmitted checksum). Carry from the most significant bit is ignored.

    Another description I found was: The checksum value contains the twos complement of the modulo 256 sum of the other words in the data message (i.e., message type, message length, and data words). The receiving equipment may calculate the modulo 256 sum of the received words and add this sum to the received checksum word. A result of zero generally indicates that the message was correctly received.

    I understand this to mean that I sum the value of all bytes in message (excl checksum), get modulo 256 of this number. get twos complement of this number and that is my checksum.

    But I am having trouble with an example message example (from design doc so I must assume it has been encoded correctly).

    unsigned char arr[] = {0x80,0x15,0x1,0x8,0x30,0x33,0x31,0x35,0x31,0x30,0x33,0x30,0x2,0x8,0x30,0x33,0x35,0x31,0x2d,0x33,0x32,0x31,0x30,0xe};
    

    So the last byte, 0xE, is the checksum. My code to calculate the checksum is as follows:

    bool isMsgValid(unsigned char arr[], int len) {
       int sum = 0;
       for(int i = 0; i < (len-1); ++i) {
          sum += arr[i];
       }
       //modulo 256 sum
       sum %= 256;
    
       char ch = sum;
    
       //twos complement
       unsigned char twoscompl = ~ch + 1;
    
       return arr[len-1] == twoscompl;
    }
    
    
    int main(int argc, char* argv[])
    {
       unsigned char arr[] = {0x80,0x15,0x1,0x8,0x30,0x33,0x31,0x35,0x31,0x30,0x33,0x30,0x2,0x8,0x30,0x33,0x35,0x31,0x2d,0x33,0x32,0x31,0x30,0xe};
       int arrsize = sizeof(arr) / sizeof(arr[0]);
    
       bool ret = isMsgValid(arr, arrsize);
    
       return 0;
    }
    

    The spec is here:= http://www.sinet.bt.com/227v3p5.pdf

    I assume I have misunderstood the algorithm required. Any idea how to create this checksum?

    Flippin spec writer made a mistake in their data example. Just spotted this then came back on here and found others spotted too. Sorry if I wasted your time. I will study responses because it looks like some useful comments for improving my code.

  • Angus Comber
    Angus Comber over 11 years
    I have been looking at the data and the size of the CallerID string is wrong. 9 instead of 8 as you say. With this corrected value the checksum value works out. Thanks though for spotting. This data was from the spec.
  • Emile Cormier
    Emile Cormier over 11 years
    No problem. You should take the others' advice about using unsigned types.