将 C CRC16 转换为 Java CRC16
Posted
技术标签:
【中文标题】将 C CRC16 转换为 Java CRC16【英文标题】:Convert C CRC16 to Java CRC16 【发布时间】:2012-10-23 22:42:44 【问题描述】:我目前正在做一个项目,有一个嵌入式系统通过无线电将数据发送到 PC。数据包最后得到一个 crc16 校验和,它是根据这个算法计算出来的:
uint16_t crc16 (const uint8_t * buffer, uint32_t size)
uint16_t crc = 0xFFFF;
if (buffer && size)
while (size--)
crc = (crc >> 8) | (crc << 8);
crc ^= *buffer++;
crc ^= ((unsigned char) crc) >> 4;
crc ^= crc << 12;
crc ^= (crc & 0xFF) << 5;
return crc;
现在我正在寻找 Java 中的等价物。我已经在这里找到了一个不错的: http://introcs.cs.princeton.edu/java/51data/CRC16CCITT.java.html
public class CRC16CCITT
public static void main(String[] args)
int crc = 0xFFFF; // initial value
int polynomial = 0x1021; // 0001 0000 0010 0001 (0, 5, 12)
// byte[] testBytes = "123456789".getBytes("ASCII");
byte[] bytes = args[0].getBytes();
for (byte b : bytes)
for (int i = 0; i < 8; i++)
boolean bit = ((b >> (7-i) & 1) == 1);
boolean c15 = ((crc >> 15 & 1) == 1);
crc <<= 1;
if (c15 ^ bit) crc ^= polynomial;
crc &= 0xffff;
System.out.println("CRC16-CCITT = " + Integer.toHexString(crc));
但这不适用于我的 C 代码。
是否有人能够为 C 和 Java 等效算法提供适应或解决方案? 谢谢!
【问题讨论】:
为什么要在每次迭代中设置crc =
,因为这与忽略除最后一个值之外的所有值相同。
那我要写什么呢? CRC ^= ?我刚刚从一个开源项目中复制了代码。
有比这更快的计算 CRcs 的方法。不停寻找。有一种表驱动的方法。
OP中的链接已经失效,这里是更新的链接:http://introcs.cs.princeton.edu/java/61data/CRC16CCITT.java.html
【参考方案1】:
在这种情况下,java 和 c 之间的主要区别在于,在 c 中您使用无符号数,而 java 只有有符号数。虽然您可以使用带符号的数字实现相同的算法,但您必须意识到符号位在移位操作中被传递,需要一个额外的“与”。
这是我的实现:
static int crc16(final byte[] buffer)
int crc = 0xFFFF;
for (int j = 0; j < buffer.length ; j++)
crc = ((crc >>> 8) | (crc << 8) )& 0xffff;
crc ^= (buffer[j] & 0xff);//byte to int, trunc sign
crc ^= ((crc & 0xff) >> 4);
crc ^= (crc << 12) & 0xffff;
crc ^= ((crc & 0xFF) << 5) & 0xffff;
crc &= 0xffff;
return crc;
【讨论】:
这是我在代码中使用的 CRC 函数 - 只要初始值相同 (0xFFFF) 且多项式相同 (0x1021),它们应该给出完全相同的结果。 我得到的包是:1 20 0 -30 -1 72 -31 -110 64 1 0 2 0 3 0 4 0 5 0 125 -7。 21 字节。包的 crc 为 -1667。我不得不将最后一个的顺序更改为字节。当我使用你的算法时,crc 给我 3377。 你应该传递给我的函数的数据是没有最后两个字节的缓冲区。您可以将我的函数更改为 for (int i = 0; i 这是它目前的样子: byte[] bx = new byte[packet.length - 2]; for(int i = 0; i 我看到我忘了计算c端的crc。但它仍然无法正常工作。包装内容为:1 20 0 -30 -1 72 -31 -110 64 1 0 2 0 3 0 4 0 5 0 51 -100。 c crc 是 13212,java crc 是你的函数 3377。以上是关于将 C CRC16 转换为 Java CRC16的主要内容,如果未能解决你的问题,请参考以下文章
请将CRC16的C语言算法,改造为JAVA语言算法,万分感谢!
CRC16算法之二:CRC16-CCITT-XMODEM算法的java实现
CRC16算法之一:CRC16-CCITT-FALSE算法的java实现
CRC16算法之三:CRC16-CCITT-MODBUS算法的java实现
javaScript中十六进制转浮点字符串转为ArrayBuffer对象ArrayBuffer转16进度字符串16进制转10进制crc校验位十六进制转包含中文的字符串(包含小程序和浏览器)