Search code examples
javaccrc16

Problems converting CRC16 function from C to JAVA without unsigned int


I have to create a CRC16 checksum for a firmware update. When I send this Data (converted from hex-string to byte[])

020000810000120000000002F001128100000C9462050C9481050C9481050C9481050C9481050C9481050C9481050C9481050C9481050C9481050C9481050C94

I get following CRC16 from the controller

-17514

now I try to check this in Java, but I can't get the same value.

This are the original functions in C:

static uint16_t crc16_update(uint16_t crc, uint8_t a)
{
  crc ^= a;
  for (unsigned i = 0; i < 8; ++i) {
    if (crc & 1)
      crc = (crc >> 1) ^ 0xA001;
    else
      crc = (crc >> 1);
  }
  return crc;
}


static uint16_t crc16(const uint8_t *b, size_t l)
{
  uint16_t crc = 0;
  while (l-- > 0)
    crc = crc16_update(crc, *b++);
  return crc;
}

this are my converted functions in java:

public static int crc16_update(int crc, int a) {
    crc ^= a;
    for (int i = 0; i < 8; ++i) {
        if ((crc & 1) != 0) {
            crc = (crc >> 1) ^ 0xA001;
        } else {
            crc = (crc << 1);
        }
    }
    return crc;
}

public static int crc16(byte[] bytes) {
    int crc = 0;
    for (byte b:bytes) {
        crc = crc16_update(crc, b);
    }
    return crc;
}

... but it doesn't work. What's wrong with it?


Solution

  • I've found the right way. Now it work's! I think the problem was the intern converting between short and int.

    public static int crc16_update(int crc, byte a) {
        crc ^= ((a+128) & 0xff);
        for (int i = 0; i < 8; ++i) {
            if ((crc & 1) != 0) {
                crc = ((crc >>> 1) ^ 0xA001) & 0xffff;
            }
            else {
                crc = (crc >>> 1) & 0xffff;
            }
        }
        return crc;
    }
    
    public static short crc16(byte[] bytes) {
        int crc = 0;
        for (byte b : bytes) {
            crc = crc16_update(crc, b);
        }
        return (short) crc;
    }