othman chanaa
othman chanaa

Reputation: 3

crc-16 IBM, 0x00 not taken in consideration

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 = %04x\n", res); //res : 7858, the result is correct

    int b = strlen(buf2);
    unsigned short res = ComputeCRC16(buf2, b);
    printf("res = %04x\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

Upvotes: 0

Views: 379

Answers (1)

Mark Adler
Mark Adler

Reputation: 112404

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;

Upvotes: 1

Related Questions