CRC16Util.java 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596
  1. package com.gzlh.utils;
  2. import cn.hutool.core.util.StrUtil;
  3. import javax.xml.bind.DatatypeConverter;
  4. public class CRC16Util {
  5. private static final int PRESET_VALUE = 0xFFFF;
  6. private static final int POLYNOMIAL = 0x8408;
  7. /**
  8. * 计算CRC16校验值
  9. * @param bytes 需要计算的字节数组
  10. * @return CRC16校验值
  11. */
  12. /**
  13. * 计算CRC16校验值
  14. * @param bytes 需要计算的字节数组
  15. * @return CRC16校验值
  16. */
  17. /**
  18. * 计算CRC16校验值
  19. *
  20. * @param bytes 需要计算的字节数组
  21. * @return CRC16校验值
  22. */
  23. public static int calculateCRC16(byte[] bytes) {
  24. int crcValue = PRESET_VALUE;
  25. for (byte b : bytes) {
  26. // 将byte转换为无符号整数
  27. int unsignedByte = b & 0xFF;
  28. crcValue = crcValue ^ unsignedByte;
  29. for (int j = 0; j < 8; j++) {
  30. if ((crcValue & 0x0001) != 0) {
  31. crcValue = (crcValue >> 1) ^ POLYNOMIAL;
  32. } else {
  33. crcValue = crcValue >> 1;
  34. }
  35. }
  36. }
  37. return swapCRC16Bytes(crcValue);
  38. }
  39. /**
  40. * 将CRC16的高低位进行交换
  41. *
  42. * @param crc 原始CRC16值
  43. * @return 交换后的CRC16值
  44. */
  45. public static int swapCRC16Bytes(int crc) {
  46. // 获取高字节和低字节
  47. int highByte = (crc >> 8) & 0xFF; // 右移8位得到高字节
  48. int lowByte = crc & 0xFF; // 与0xFF相与得到低字节
  49. // 交换高低字节
  50. return (lowByte << 8) | highByte;
  51. }
  52. /**
  53. * 获取CRC16校验值的十六进制字符串
  54. *
  55. * @param bytes 需要计算的字节数组
  56. * @return CRC16校验值的十六进制字符串
  57. */
  58. public static String getCRC16Hex(byte[] bytes) {
  59. int crc = calculateCRC16(bytes);
  60. return String.format("%04X", crc);
  61. }
  62. public static String getCRC16Hex(String hexStr) {
  63. int crc = calculateCRC16(DatatypeConverter.parseHexBinary(hexStr));
  64. return String.format("%04X", crc);
  65. }
  66. // 测试方法
  67. public static void main(String[] args) {
  68. System.out.println("E20000001A0C02721820ECB8".length());
  69. // 测试数据
  70. String command = "2D000101030CE200001B170902202610C3A60CFEDC000000000000008102BA0CE200001D8817007817602D1F793F";
  71. int len = command.length();
  72. String crcStr = StrUtil.sub(command, len - 4, len);
  73. String packetStr = StrUtil.sub(command, 0, len - 4);
  74. String dataPack=StrUtil.subSuf(packetStr,10);
  75. int cardNum=Integer.parseInt(StrUtil.sub(packetStr,8,10));
  76. int startIndex=2;
  77. for (int i = 0; i < cardNum; i++) {
  78. String cardHex = StrUtil.sub(dataPack, startIndex, startIndex+24);
  79. startIndex += 26;
  80. System.out.println(cardHex);
  81. }
  82. }
  83. }