Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ISO/IEC13239 CRC16 Implementation

Tags:

java

crc16

I need a CRC16 implementation for NFC Tags. As the standard tolds me this is ISO/IEC13239 and a sample C code is provided. I translated this code into Java but it gives me wrong results:

private static final char POLYNOMIAL = 0x8404;
private static final char PRESET_VALUE = 0xFFFF;

public static int crc16(byte[] data) {
char current_crc_value = PRESET_VALUE;
for (int i = 0; i < data.length; i++) {
    current_crc_value = (char) (current_crc_value ^ ((char) data[i]));
    for (int j = 0; j < 8; j++) {
    if ((current_crc_value & 0x0001) == 0x0001) {
        current_crc_value = (char) ((current_crc_value >>> 1) ^ POLYNOMIAL);
    } else {
        current_crc_value = (char) (current_crc_value >>> 1);
    }
    }
}
current_crc_value = (char) ~current_crc_value;

return current_crc_value;
}

As the standard tells me a byte sequence of 1,2,3,4 should create a CRC Value of 0x3991 A C Version is here on Page 42: http://www.waazaa.org/download/fcd-15693-3.pdf

Also other CRC Implementations does not work: crc16 implementation java The first gives me 0x9e33, the second 0x0FA1 (my implementation by the way says 0xE1E5)

Does someone find an error in my sample or is there another CRC16 Implementation thats really works?

like image 892
reox Avatar asked Mar 22 '23 17:03

reox


2 Answers

Your answer is pretty close, but I think there may be some problems with masking and polynomials. Here are some tweaks that seem to work for me:

private static final int POLYNOMIAL   = 0x8408;
private static final int PRESET_VALUE = 0xFFFF;

public static int crc16(byte[] data)
{
  int current_crc_value = PRESET_VALUE;
  for (int i = 0; i < data.length; i++ )
  {
    current_crc_value ^= data[i] & 0xFF;
    for (int j = 0; j < 8; j++)
    {
      if ((current_crc_value & 1) != 0)
      {
        current_crc_value = (current_crc_value >>> 1) ^ POLYNOMIAL;
      }
      else
      {
        current_crc_value = current_crc_value >>> 1;
      }
    }
  }
  current_crc_value = ~current_crc_value;

  return current_crc_value & 0xFFFF;
}
like image 196
clstrfsck Avatar answered Apr 02 '23 16:04

clstrfsck


For a start - the PDF has:

#define POLYNOMIAL 0x8408 // x^16 + x^12 + x^5 + 1

while you have

private static final char POLYNOMIAL = 0x8404;

This would certainly cause issues - please fix that and let us know if that was the problem.

I am a little concerned that they state that 0x8408 is equivalent to x^16 + x^12 + x^5 + 1 because it is not, that polynomial would be represented by 0x8811. 0x8408 would represent x^16 + x^11 + x^4 which is unlikely to be correct as it is neither prime n'or primitive. For that matter neither is 0x8404.

like image 40
OldCurmudgeon Avatar answered Apr 02 '23 14:04

OldCurmudgeon