package publicway;
|
/**
|
* Modbus CRC16 ¹¤¾ßÀà
|
* <p>
|
* Ìṩ¾²Ì¬·½·¨ calculate(String hexString) ½ÓÊÕÒ»¸ö²»´ø¿Õ¸ñµÄÊ®Áù½øÖÆ×Ö·û´®£¬
|
* ·µ»Ø 4 λµÄÊ®Áù½øÖÆ CRC УÑéÂ루Сд£¬²»´ø 0x ǰ׺£©£¬Ó빤³ÌÖÐ HexUtil.calculate ±£³ÖÒ»Ö¡£
|
*/
|
public class CRC16Modbus {
|
|
/**
|
* ¼ÆËã Modbus CRC16£¨¶àÏîʽ 0xA001£¬³õʼֵ 0xFFFF£©¡£
|
*
|
* @param hexString ÊäÈëµÄÊ®Áù½øÖÆ×Ö·û´®£¬ÀýÈç "DDCC000EF0..."£¨´óСд¾ù¿É£¬ÔÊÐí°üº¬¿Õ¸ñ£©
|
* @return 4 λʮÁù½øÖÆ×Ö·û´®£¨Ð¡Ð´£©£¬ÀýÈç "f1a3"¡£Èç¹ûÊäÈëΪ¿Õ·µ»Ø "0000"¡£
|
*/
|
public static String calculate(String hexString) {
|
if (hexString == null || hexString.trim().length() == 0) {
|
return "0000";
|
}
|
|
byte[] data = hexStringToBytes(hexString);
|
int crc = 0xFFFF;
|
for (byte b : data) {
|
crc ^= b & 0xFF;
|
for (int i = 0; i < 8; i++) {
|
if ((crc & 1) == 1) {
|
crc = (crc >>> 1) ^ 0xA001;
|
} else {
|
crc = crc >>> 1;
|
}
|
}
|
}
|
String result = String.format("%4s", Integer.toHexString(crc)).replace(' ', '0');
|
return result.toUpperCase();
|
}
|
|
// ¼òµ¥µÄ hex -> byte[] ת»»£¬Ö§³Ö´ø»ò²»´ø¿Õ¸ñµÄ×Ö·û´®£¬³¤¶ÈÎªÆæÊýʱÔÚǰ²¹ 0
|
private static byte[] hexStringToBytes(String hex) {
|
String s = hex.replaceAll("\\s+", "");
|
if (s.length() % 2 != 0) {
|
s = "0" + s;
|
}
|
int len = s.length() / 2;
|
byte[] data = new byte[len];
|
for (int i = 0; i < len; i++) {
|
int pos = i * 2;
|
data[i] = (byte) Integer.parseInt(s.substring(pos, pos + 2), 16);
|
}
|
return data;
|
}
|
|
public static void main(String args[]) {
|
System.out.println(calculate("DD CC 00 08 F0 01 51 5A A5 5A A5 11"));
|
}
|
|
}
|