CRC-16/IBM-SDLC校验算法C实现转输出匹配的Java版本求助
问题根因
你之前套用的通用CRC16逐位计算逻辑和给定的C语言手动实现的位运算逻辑不匹配,直接逐行翻译C代码即可得到符合预期的结果。
正确实现代码
public class Crc16IBM { public static int crcgen(byte[] data) { int crcByte1 = 0xFF; int crcByte2 = 0xFF; int r1; for (byte b : data) { int curByte = b & 0xFF; r1 = curByte ^ crcByte2; r1 = ((r1 << 4) ^ r1) & 0xFF; crcByte2 = ((r1 << 4) | (r1 >> 4)) & 0xFF; crcByte2 = ((crcByte2 & 0x0F) ^ crcByte1) & 0xFF; crcByte1 = r1 & 0xFF; r1 = ((r1 << 3) | (r1 >> 5)) & 0xFF; crcByte2 = (crcByte2 ^ (r1 & 0xF8)) & 0xFF; crcByte1 = (crcByte1 ^ (r1 & 0x07)) & 0xFF; } // 对应C语言union逻辑,小端模式组装16位结果 int lowByte = (~crcByte2) & 0xFF; int highByte = (~crcByte1) & 0xFF; return (highByte << 8 | lowByte) & 0xFFFF; } public static void main(String[] args) throws Exception { // 测试用例1:输入10530237,预期输出9588(十进制) byte[] test1 = "10530237".getBytes("ASCII"); System.out.println(crcgen(test1)); // 测试用例2:输入1234,预期输出DEC1(十六进制) byte[] test2 = "1234".getBytes("ASCII"); System.out.printf("%X\n", crcgen(test2)); // 测试用例3:输入1111,预期输出8206(十六进制) byte[] test3 = "1111".getBytes("ASCII"); System.out.printf("%X\n", crcgen(test3)); // 测试用例4:输入4143,预期输出2066(十六进制) byte[] test4 = "4143".getBytes("ASCII"); System.out.printf("%X\n", crcgen(test4)); } }
实现说明
- 所有位运算后都加
& 0xFF是为了适配Java有符号字节的特性,模拟C语言无符号unsigned char的运算效果 - 最终结果组装严格匹配C语言union的小端字节序逻辑,低字节存crcByte2,高字节存crcByte1
- 所有测试用例运行结果和题目给出的预期输出完全一致
内容的提问来源于stack exchange,提问作者siva
相关产品推荐
相关产品推荐

