DataCheckUtil.java 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111
  1. package com.zksy.gas.utils;
  2. /**
  3. * @Description
  4. * @Date 2025- 03-06-上午 9:02
  5. * @auther tuDouSi
  6. */
  7. public class DataCheckUtil {
  8. /**
  9. *
  10. * @description: crc16校验,输入一个数据,返回一个数组.
  11. * @param str
  12. * @return 返回两个校验码,低字节在前,高字节在后
  13. *
  14. */
  15. public static String crc16(String str) {
  16. int[] data = hexStringToIntArray(str);
  17. int xda, xdapoly;
  18. int i, j, xdabit;
  19. xda = 0xFFFF;
  20. xdapoly = 0xA001;
  21. for (i = 0; i < data.length; i++) {
  22. xda ^= data[i];
  23. for (j = 0; j < 8; j++) {
  24. xdabit = (int) (xda & 0x01);
  25. xda >>= 1;
  26. if (xdabit == 1) {
  27. xda ^= xdapoly;
  28. }
  29. }
  30. }
  31. byte[] temdata = new byte[2];
  32. temdata[0] = (byte) (xda & 0xFF);
  33. temdata[1] = (byte) (xda >> 8);
  34. return bytesToHexString(temdata);
  35. }
  36. /**
  37. *
  38. * @description: crc16校验,
  39. * @param str
  40. * @return 返回两个校验码,高字节在前,低字节在后
  41. *
  42. */
  43. public static String crc16Tall(String str) {
  44. int[] data = hexStringToIntArray(str);
  45. int xda, xdapoly;
  46. int i, j, xdabit;
  47. xda = 0xFFFF;
  48. xdapoly = 0xA001;
  49. for (i = 0; i < data.length; i++) {
  50. xda ^= data[i];
  51. for (j = 0; j < 8; j++) {
  52. xdabit = (int) (xda & 0x01);
  53. xda >>= 1;
  54. if (xdabit == 1) {
  55. xda ^= xdapoly;
  56. }
  57. }
  58. }
  59. // 关键修改:先放高位字节,再放低位字节
  60. byte[] temdata = new byte[2];
  61. temdata[0] = (byte) (xda >> 8); // 高位字节
  62. temdata[1] = (byte) (xda & 0xFF); // 低位字节
  63. return bytesToHexString(temdata);
  64. }
  65. // 将十六进制字符串转换为整数数组
  66. private static int[] hexStringToIntArray(String str) {
  67. if (str.length() % 2 != 0) {
  68. throw new IllegalArgumentException("Hex string length must be even");
  69. }
  70. int[] result = new int[str.length() / 2];
  71. for (int i = 0; i < str.length(); i += 2) {
  72. result[i / 2] = Integer.parseInt(str.substring(i, i + 2), 16);
  73. }
  74. return result;
  75. }
  76. // 将字节数组转换为十六进制字符串
  77. private static String bytesToHexString(byte[] bytes) {
  78. StringBuilder sb = new StringBuilder();
  79. for (byte b : bytes) {
  80. sb.append(String.format("%02X", b));
  81. }
  82. return sb.toString();
  83. }
  84. public static int calcChecksum(byte[] data, int offset, int length) {
  85. int sum = 0;
  86. for (int i = offset; i < offset + length; i++) {
  87. sum += (data[i] & 0xFF);
  88. }
  89. return (0xFF - (sum & 0xFF)) & 0xFF;
  90. }
  91. /**
  92. * 仅对数据累加后取低8位
  93. * @param data 待计算字节数组
  94. * @param offset 起始索引
  95. * @param length 计算长度
  96. * @return 8位校验结果
  97. */
  98. static int calcSumOnly(byte[] data, int offset, int length) {
  99. int sum = 0;
  100. for (int i = offset; i < offset + length; i++) {
  101. sum += (data[i] & 0xFF); // 累加每个字节的无符号值
  102. }
  103. return sum & 0xFF; // 仅取低8位,无FF-操作
  104. }
  105. }