【发布时间】:2013-08-20 08:45:00
【问题描述】:
我需要 NFC 标签的 CRC16 实现。正如标准告诉我的那样,这是 ISO/IEC13239 并提供了示例 C 代码。 我将这段代码翻译成 Java,但它给了我错误的结果:
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;
}
正如标准告诉我的那样,1,2,3,4 的字节序列应该创建0x3991 的 CRC 值
C 版本在第 42 页:http://www.waazaa.org/download/fcd-15693-3.pdf
其他 CRC 实现也不起作用:crc16 implementation java
第一个给我0x9e33,第二个给我0x0FA1(我的实现顺便说一下0xE1E5)
是否有人在我的示例中发现了错误,或者是否有另一个真正有效的 CRC16 实现?
【问题讨论】:
-
CRC 需要使用 16 位宽且无符号的变量进行操作。您的变量 crc_current_value 是一个字符。你也有很多演员要通过例行程序来完成......
-
你需要知道有一个比这更快的算法,使用预先计算的表。
-
@EJP:你的意思是链接中的那个?这给了我完全不同的结果......
-
您必须调整多项式和初始值以适合您的情况。它确实有效,我已经使用了 25 年,在 Java 中使用了 17 年。