majkx00
majkx00

Reputation: 23

Crc ccitt (0x1d0f) calculating in C

I have an array of values in hexadecimal. I have pre-calculated CRC-CCITT (0x1d0f) of it which is : 0xD7F2

I wrote an alghoritm based on working crc alghoritm wrote in javascript , which I tested with same entry of data (calculation here).

I rewrote it inC, but unfortunatelly, I'm getting different output than expected, actually: 0xB5DB.

So, my question is: is possible to have problem inside alghoritm? Could wrong data types causing problem?

Here is an example with a simple array of size 2. Calculated result by calculator is 0x9770, Result of my alghoritm is 0x5D80.

Calculation alghorithm:

unsigned int crcTest[2] = {0xB6FE,0x8C4A};

int main (void){
    unsigned int crc = doCrc(crcTest,2);
    printf("Correct CRC16-CCITT is: 0x9770\n");
    printf("Calculated result func : 0x%X\n", crc);
    return 0;
}    

unsigned int doCrc(unsigned int *data, int size)
    {
        int i, j;
        unsigned int crc = 0x1d0f;
        for (i = 0; i < size; i++){
            unsigned int xr = data[i] << 8;
            crc = crc^xr;

            for (j = 0; j < 8; j++)
            {
                if (crc & 0x8000){
                    crc = (crc << 1);
                    crc = crc ^ 0x1021;
                }
                else{
                    crc = crc << 1;
                }
            }
        }
        crc = crc & 0xFFFF;
        return crc;
    }

Whole source code main.c : Download here

JavaScript code which actually works :

CRC1D0F: function() {
        var str = this.CleanedString;
        var crc = 0x1d0f;
        for (var c = 0; c < str.length; c++) {
            crc ^= str.charCodeAt(c) << 8;
            for (var i = 0; i < 8; i++) {
                if (crc & 0x8000)
                    crc = (crc << 1) ^ 0x1021;
                else
                    crc = crc << 1;
            }
        }
        return crc & 0xFFFF;

Upvotes: 2

Views: 2373

Answers (1)

Jabberwocky
Jabberwocky

Reputation: 50902

Your code is almost correct:

It should be:

unsigned int doCrc(unsigned char *data, int size)

instead of:

unsigned int doCrc(unsigned int *data, int size)

This works:

#include <stdio.h>
#include <stdlib.h>

unsigned int doCrc(unsigned char *data, int size)
{
  int i, j;
  unsigned int crc = 0x1d0f;
  for (i = 0; i < size; i++) {
    unsigned int xr = data[i] << 8;
    crc = crc ^ xr;

    for (j = 0; j < 8; j++)
    {
      if (crc & 0x8000) {
        crc = (crc << 1);
        crc = crc ^ 0x1021;
      }
      else {
        crc = crc << 1;
      }
    }
  }
  crc = crc & 0xFFFF;
  return crc;
}    

unsigned char data[] = "1234567890";

int main(int argc, char *argv[])
{
  printf("%0x\n", doCrc(data, strlen(data)));
}

Expected output:

57d8

which is the same as we get here.

Upvotes: 5

Related Questions