Home > Software design >  crc-16 IBM, 0x00 not taken in consideration
crc-16 IBM, 0x00 not taken in consideration

Time:12-14

I did test a crc-16/ibm implementation i found on the net. when I test it with hex byte array it works fine but if I include some 0x00 values, then it doesn't give the proper result. here is its code

unsigned short ComputeCRC16(const unsigned char* buf, unsigned int len) {
    unsigned short crc = 0;
    for (unsigned int j = 0; j < len; j  )
    {
        unsigned char b = buf[j];
        for (unsigned char i = 0; i < 8; i  )
        {
            crc = ((b ^ (unsigned char)crc) & 1) ? ((crc >> 1) ^ 0xA001) : (crc >> 1);
            b >>= 1;
        }
    }
    return crc;
}

I tested it with this code:

int main() {

    //fe   b5     5f       f7
    unsigned char buf1[4096] = { 0xfe, 0xb5, 0x5f, 0xf7 };

    //fe   b5     00    5f     f7   00
    unsigned char buf2[4096] = { 0xfe, 0xb5, 0x00, 0x5f, 0xf7, 0x00 };

    int a = strlen(buf1);
    unsigned short res = ComputeCRC16(buf1, a);
    printf("res = x\n", res); //res : 7858, the result is correct

    int b = strlen(buf2);
    unsigned short res = ComputeCRC16(buf2, b);
    printf("res = x\n", res); //res : d781, the result is not correct
    return 0;                   //the correct result : 26EE
}

to verify the result I use this website: https://www.lammertbies.nl/comm/info/crc-calculation

CodePudding user response:

Your CRC routine gives correct results. It is your test that's wrong. strlen(p) returns how many bytes there are before the first zero byte at p. For buf2, that's four, not five as you intended. For buf1 it's not even defined, since there can be anything in memory after that array. You might be getting four, if the compiler happened to put zeros after the array.

For testing, you should simply provide len manually. (buf1, 4), (buf2, 5).

By the way, that code could be more efficient. It doesn't have to test with b every time. Just exclusive-oring with b to start has the same effect:

    crc ^= buf[j];
    for (unsigned char i = 0; i < 8; i  )
        crc = crc & 1 ? (crc >> 1) ^ 0xa001 : crc >> 1;
  • Related