Java C等效于C CRC16

时间:2015-06-17 11:40:38

标签: java c crc16

我需要将N2:02 CRC16方法转换为C。问题是我对Java和字节操作不太好。

C代码:

C

这是我尝试转换它的尝试。不确定这是否正确。

static const unsigned short crc16_table[256] =
{
 0x0000,0xC0C1,0xC181,0x0140,0xC301,0x03C0,0x0280,0xC241,
 ...  /* Removed for brevity */
 0x8201,0x42C0,0x4380,0x8341,0x4100,0x81C1,0x8081,0x4040
};

unsigned short crc16 (const void *data, unsigned data_size)
{
 if (!data || !data_size)
 return 0;
 unsigned short crc = 0;
 unsigned char* buf = (unsigned char*)data;
 while (data_size--)
 crc = (crc >> 8) ^ crc16_table[(unsigned char)crc ^ *buf++];
 return crc;
}

问题: 我移植到Java是否正确?

修改

修改后的private static int[] table = { 0x0000,0xC0C1,0xC181,0x0140,0xC301,0x03C0,0x0280,0xC241,0xC601,0x06C0,0x0780,0xC741, ... // Removed for brevity 0x4400,0x84C1,0x8581,0x4540,0x8701,0x47C0,0x4680,0x8641,0x8201,0x42C0,0x4380,0x8341, 0x4100,0x81C1,0x8081,0x4040 }; public static int getCode (String[] data){ if (data.length == 0) { return 0; } int crc = 0; for (String item : data) { byte[] bytes = item.getBytes(); for (byte b : bytes) { crc = (crc >>> 8) ^ table[(crc ^ b) & 0xff]; //this confuses me } } return crc; } 工作方法(感谢很棒的答案):

crc16

返回十进制值。 CRC16代码需要是十六进制的。我使用此方法转换为基数16.使用public static int getCode(String data) { if (data == null || data.equals("")) { return 0; } int crc = 0x0000; byte[] bytes = data.getBytes(); for (byte b : bytes) { crc = (crc >>> 8) ^ table[(crc ^ b) & 0xff]; } return crc; } 收到的crc执行此操作:

dec2m(crc, 16)

为了测试结果,您可以使用this site(感谢@greenaps)

2 个答案:

答案 0 :(得分:2)

你写的内容看起来很好,正如Mohit Jain所说。但是你的函数与原始的C函数不同:你接受一个String数组,而C代码接受一个void *,以及一个以字节为单位的长度。因此,如果您使用转换函数来验证UTF-8和Latin1平台之间包含非ASCII字符的字符串,它将给出不同的结果,因为对于Latin1,“éè”将给出2个字节0xe9,{ {1}},使用UTF-8时,您将获得4个字节:0xe80xc30xa90xc3 =>你的CRC功能会产生不同的结果。

恕我直言,你应该坚持原始代码,只计算字节数组的CRC。您可以强制始终使用相同的字符集(例如UTF-8),但是仍然很难将结果与C实现进行比较,并且您将无法计算原始字节数组(二进制数据)的CRC。

无论如何,确保你的实现给出与原始C一样的结果的唯一方法是采用任意字节串(例如,所有字节从0到255),将其传递给一端的C例程,另一方面给你一个java并比较两个CRC。

答案 1 :(得分:1)

您翻译的c代码函数调用crc16 (const void *data, unsigned data_size)错误。

public static int getCode (String[] data)

应该是

public static int getCode (String data)

此外,您还可以在Wialon pdf中看到您需要getCode (String)而不是getCode(String[])

将收到的String转换为字节数组。