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?
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;
}
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
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With