Search code examples
cchecksum

Converting a checksum algorithm from Python to C


There is a checksum algorithm for the networks in some Honda vehicles that computes an integer between 0-15 for the provided data. I'm trying to convert it to plain C, but I think I'm missing something, as I get different results in my implementation.

While the Python algorithm computes 6 for "ABC", mine computes -10, which is weird. Am I messing something up with the bit shifting?

The Python algorithm:

def can_cksum(mm):
  s = 0

  for c in mm:
    c = ord(c)
    s += (c>>4)
    s += c & 0xF

  s = 8-s
  s %= 0x10

  return s

My version, in C:

int can_cksum(unsigned char * data, unsigned int len) {
    int result = 0;

    for (int i = 0; i < len; i++) {
        result += data[i] >> 4;
        result += data[i] & 0xF;
    }

    result = 8 - result;
    result %= 0x10;

    return result;
}

Solution

  • No, the problem is the modulus. Python follows the sign of the right operand, and C follows the sign of the left. Mask with 0x0f instead to avoid this.

    result = 8 - result;
    result &= 0x0f;