将 C CRC16 转换为 Java CRC16
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/13209364/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Convert C CRC16 to Java CRC16
提问by tellob
I am currently working on a project, having an embedded system sending data to a PC via radio. The packets get a crc16 checksum at the end and it's calculated based on this algorithm:
我目前正在做一个项目,有一个嵌入式系统通过无线电向 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;
}
Now I am looking for an equivalent in Java. I already found a good one here: http://introcs.cs.princeton.edu/java/51data/CRC16CCITT.java.html
现在我正在寻找 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));
}
}
But this doesnt work with my C Code.
但这不适用于我的 C 代码。
Is anybody able to deliver an adaption or solution for a C and Java equivalent algorithm? Thank you!
有人能够为 C 和 Java 等效算法提供改编或解决方案吗?谢谢!
回答by thedayofcondor
The major difference between java and c in this case is the fact in c you use unsigned numbers and java has only signed numbers. While you can implement the same algorithm with signed numbers, you have to be aware of the fact the sign bit is carried over on shift operations, requiring an extra "and".
在这种情况下,java 和 c 之间的主要区别在于,在 c 中您使用无符号数,而 java 只有有符号数。虽然您可以使用有符号数实现相同的算法,但您必须注意符号位在移位操作中被继承的事实,需要额外的“和”。
This is my implementation:
这是我的实现:
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;
}