Search code examples
javaccrc16

Java equivalent for C CRC16


I need to convert C CRC16 method to Java. The problem is I'm not that good with C and Bytes operations.

C code:

static const unsigned short crc16_table[256] =
{
 0x0000,0xC0C1,0xC181,0x0140,0xC301,0x03C0,0x0280,0xC241,
 ...  /* Removed for brevity */
 0x8201,0x42C0,0x4380,0x8341,0x4100,0x81C1,0x8081,0x4040
};

unsigned short crc16 (const void *data, unsigned data_size)
{
 if (!data || !data_size)
 return 0;
 unsigned short crc = 0;
 unsigned char* buf = (unsigned char*)data;
 while (data_size--)
 crc = (crc >> 8) ^ crc16_table[(unsigned char)crc ^ *buf++];
 return crc;
}

And that's my attempt to convert it. Not sure if that's correct.

private static int[] table = {
    0x0000,0xC0C1,0xC181,0x0140,0xC301,0x03C0,0x0280,0xC241,0xC601,0x06C0,0x0780,0xC741,
    ...    // Removed for brevity
    0x4400,0x84C1,0x8581,0x4540,0x8701,0x47C0,0x4680,0x8641,0x8201,0x42C0,0x4380,0x8341, 0x4100,0x81C1,0x8081,0x4040
};

public static int getCode (String[] data){
    if (data.length == 0) {
        return 0;
    }
    int crc = 0;
    for (String item : data) {
        byte[] bytes = item.getBytes();
        for (byte b : bytes) {
            crc = (crc >>> 8) ^ table[(crc ^ b) & 0xff]; //this confuses me
        }
    }
    return crc;
}

Question: Is my porting to Java correct?


EDIT:

Modified crc16 working method (thanks to great answers):

public static int getCode(String data) {
    if (data == null || data.equals("")) {
        return 0;
    }
    int crc = 0x0000;
    byte[] bytes = data.getBytes();
    for (byte b : bytes) {
        crc = (crc >>> 8) ^ table[(crc ^ b) & 0xff];
    }
    return crc;
}

This returns Decimal value. And CRC16 code needs to be Hexadecimal. I used this method to convert to base 16. Do it with received crc like dec2m(crc, 16):

static String dec2m(int N, int m) {
    String s = "";
    for (int n = N; n > 0; n /= m) {
        int r = n % m;
        s = r < 10 ? r + s : (char) ('A' - 10 + r) + s;
    }
    return s;
}

For testing your results you could use this site (Thanks to @greenaps)


Solution

  • Your translated the c code function call crc16 (const void *data, unsigned data_size) wrong.

    public static int getCode (String[] data)
    

    should be

    public static int getCode (String data)
    

    Moreover you can also see in the Wialon pdf that you need a getCode (String) and not a getCode(String[]).

    Converting the received String to a byte array stands.