CRC16.java 9.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252
  1. package com.sig.app.common.utils;
  2. /**
  3. * CRC16_CCITT: Polynomial x16+x12+x5+1 (0x1021), initial value 0x0000, low bit first, high bit after, result is exclusive to 0x0000
  4. * CRC16_CCITT_FALSE: Polynomial x16+x12+x5+1 (0x1021), initial value 0xFFFF, low bit is after, high bit is first, result is exclusive to 0x0000
  5. * CRC16_XMODEM: Polynomial x16+x12+x5+1 (0x1021), initial value 0x0000, low bit after, high bit first, result is XOR0
  6. * CRC16_X25: Polynomial x16+x12+x5+1 (0x1021), initial value 0xffff, low bit first, high bit after, result is XORIF 0xFFFF
  7. * CRC16_MODBUS: Polynomial x16+x15+x2+1 (0x8005), initial value 0xFFFF, low bit first, high bit after, result is X2000000 exclusive OR
  8. * CRC16_IBM: Polynomial x16+x15+x2+1 (0x8005), initial value 0x0000, low bit first, high bit after, result is XOR0
  9. * CRC16_MAXIM: Polynomial x16+x15+x2+1 (0x8005), initial value 0x0000, low bit first, high bit after, result is XORIF 0xFFFF
  10. * CRC16_USB: Polynomial x16+x15+x2+1 (0x8005), initial value 0xFFFF, low bit first, high bit after, result is XORIF 0xFFFF
  11. * <p>
  12. * (1), preset a 16-bit register to hexadecimal FFFF (that is, all 1), call this register a CRC register;
  13. * (2), the first 8-bit binary data (the first byte of the communication information frame) is different from the lower 8 bits of the 16-bit CRC register, the result is placed in the CRC register, the upper eight bits of data are not Change
  14. * (3), shift the contents of the CRC register one bit to the right (toward the low position) to fill the highest bit with 0, and check the shifted out bit after the right shift;
  15. * (4) If the shift bit is 0: repeat step 3 (shift one bit right again); if the shift bit is 1, the CRC register is XORed with the polynomial A001 (1010 0000 0000 0001);
  16. * (5), repeat steps 3 and 4 until the right shift 8 times, so that the entire 8-bit data is processed;
  17. * (6), repeat steps 2 to 5, and worker the next byte of the communication information frame;
  18. * (7), after all the bytes of the communication information frame are calculated according to the above steps, the high and low bytes of the obtained 16-bit CRC register are exchanged;
  19. * (8), the final CRC register content is: CRC code.
  20. * <p>
  21. * The polynomial 0xA001 in the above calculation step is the result of 0x8005 bitwise reversal.
  22. * 0x8408 is the result of 0x1021 bitwise reversal.
  23. * Online verification tool
  24. * http://www.ip33.com/crc.html
  25. * https://blog.csdn.net/htmlxx/article/details/17369105
  26. * <p>
  27. * Author:Water
  28. * Time:2018/11/19 0019 15:03
  29. */
  30. public class CRC16 {
  31. /**
  32. * CRC16_CCITT: Polynomial x16+x12+x5+1 (0x1021), initial value 0x0000, low bit first, high bit after, result is exclusive to 0x0000
  33. * 0x8408 is the result of 0x1021 bitwise reversal.
  34. *
  35. * @param buffer
  36. * @return
  37. */
  38. public static int CRC16_CCITT(byte[] buffer) {
  39. int wCRCin = 0x0000;
  40. int wCPoly = 0x8408;
  41. for (byte b : buffer) {
  42. wCRCin ^= ((int) b & 0x00ff);
  43. for (int j = 0; j < 8; j++) {
  44. if ((wCRCin & 0x0001) != 0) {
  45. wCRCin >>= 1;
  46. wCRCin ^= wCPoly;
  47. } else {
  48. wCRCin >>= 1;
  49. }
  50. }
  51. }
  52. // wCRCin=(wCRCin<<8)|(wCRCin>>8);
  53. // wCRCin &= 0xffff;
  54. return wCRCin ^= 0x0000;
  55. }
  56. /**
  57. * CRC-CCITT (0xFFFF)
  58. * CRC16_CCITT_FALSE: Polynomial x16+x12+x5+1 (0x1021), initial value 0xFFFF, low bit is after, high bit is first, result is exclusive to 0x0000
  59. *
  60. * @param buffer
  61. * @return
  62. */
  63. public static int CRC16_CCITT_FALSE(byte[] buffer) {
  64. int wCRCin = 0xffff;
  65. int wCPoly = 0x1021;
  66. for (byte b : buffer) {
  67. for (int i = 0; i < 8; i++) {
  68. boolean bit = ((b >> (7 - i) & 1) == 1);
  69. boolean c15 = ((wCRCin >> 15 & 1) == 1);
  70. wCRCin <<= 1;
  71. if (c15 ^ bit)
  72. wCRCin ^= wCPoly;
  73. }
  74. }
  75. wCRCin &= 0xffff;
  76. return wCRCin ^= 0x0000;
  77. }
  78. /**
  79. * CRC-CCITT (XModem)
  80. * CRC16_XMODEM: Polynomial x16+x12+x5+1 (0x1021), initial value 0x0000, low bit after, high bit first, result is XOR0
  81. *
  82. * @param buffer
  83. * @return
  84. */
  85. public static int CRC16_XMODEM(byte[] buffer) {
  86. int wCRCin = 0x0000; // initial value 65535
  87. int wCPoly = 0x1021; // 0001 0000 0010 0001 (0, 5, 12)
  88. for (byte b : buffer) {
  89. for (int i = 0; i < 8; i++) {
  90. boolean bit = ((b >> (7 - i) & 1) == 1);
  91. boolean c15 = ((wCRCin >> 15 & 1) == 1);
  92. wCRCin <<= 1;
  93. if (c15 ^ bit)
  94. wCRCin ^= wCPoly;
  95. }
  96. }
  97. wCRCin &= 0xffff;
  98. return wCRCin ^= 0x0000;
  99. }
  100. /**
  101. * CRC16_X25: Polynomial x16+x12+x5+1 (0x1021), initial value 0xffff, low bit first, high bit after, result is XORIF 0xFFFF
  102. * 0x8408 is the result of 0x1021 bitwise reversal.
  103. *
  104. * @param buffer
  105. * @return
  106. */
  107. public static int CRC16_X25(byte[] buffer) {
  108. int wCRCin = 0xffff;
  109. int wCPoly = 0x8408;
  110. for (byte b : buffer) {
  111. wCRCin ^= ((int) b & 0x00ff);
  112. for (int j = 0; j < 8; j++) {
  113. if ((wCRCin & 0x0001) != 0) {
  114. wCRCin >>= 1;
  115. wCRCin ^= wCPoly;
  116. } else {
  117. wCRCin >>= 1;
  118. }
  119. }
  120. }
  121. return wCRCin ^= 0xffff;
  122. }
  123. /**
  124. * CRC-16 (Modbus)
  125. * CRC16_MODBUS: Polynomial x16+x15+x2+1 (0x8005), initial value 0xFFFF, low bit first, high bit after, result is X2000000 exclusive OR
  126. * 0xA001 is the result of 0x8005 bitwise reversal
  127. *
  128. * @param buffer
  129. * @return
  130. */
  131. public static int CRC16_MODBUS(byte[] buffer) {
  132. int wCRCin = 0xffff;
  133. int POLYNOMIAL = 0xa001;
  134. for (byte b : buffer) {
  135. wCRCin ^= ((int) b & 0x00ff);
  136. for (int j = 0; j < 8; j++) {
  137. if ((wCRCin & 0x0001) != 0) {
  138. wCRCin >>= 1;
  139. wCRCin ^= POLYNOMIAL;
  140. } else {
  141. wCRCin >>= 1;
  142. }
  143. }
  144. }
  145. return wCRCin ^= 0x0000;
  146. }
  147. /**
  148. * CRC-16
  149. * CRC16_IBM: Polynomial x16+x15+x2+1 (0x8005), initial value 0x0000, low bit first, high bit after, result is XOR0
  150. * 0xA001 is the result of 0x8005 bitwise reversal
  151. *
  152. * @param buffer
  153. * @return
  154. */
  155. public static int CRC16_IBM(byte[] buffer) {
  156. int wCRCin = 0x0000;
  157. int wCPoly = 0xa001;
  158. for (byte b : buffer) {
  159. wCRCin ^= ((int) b & 0x00ff);
  160. for (int j = 0; j < 8; j++) {
  161. if ((wCRCin & 0x0001) != 0) {
  162. wCRCin >>= 1;
  163. wCRCin ^= wCPoly;
  164. } else {
  165. wCRCin >>= 1;
  166. }
  167. }
  168. }
  169. return wCRCin ^= 0x0000;
  170. }
  171. /**
  172. * CRC16_MAXIM: Polynomial x16+x15+x2+1 (0x8005), initial value 0x0000, low bit first, high bit after, result is XORIF 0xFFFF
  173. * 0xA001 is the result of 0x8005 bitwise reversal
  174. *
  175. * @param buffer
  176. * @return
  177. */
  178. public static int CRC16_MAXIM(byte[] buffer) {
  179. int wCRCin = 0x0000;
  180. int wCPoly = 0xa001;
  181. for (byte b : buffer) {
  182. wCRCin ^= ((int) b & 0x00ff);
  183. for (int j = 0; j < 8; j++) {
  184. if ((wCRCin & 0x0001) != 0) {
  185. wCRCin >>= 1;
  186. wCRCin ^= wCPoly;
  187. } else {
  188. wCRCin >>= 1;
  189. }
  190. }
  191. }
  192. return wCRCin ^= 0xffff;
  193. }
  194. /**
  195. * CRC16_USB: Polynomial x16+x15+x2+1 (0x8005), initial value 0xFFFF, low bit first, high bit after, result is XORIF 0xFFFF
  196. * 0xA001 is the result of 0x8005 bitwise reversal
  197. *
  198. * @param buffer
  199. * @return
  200. */
  201. public static int CRC16_USB(byte[] buffer) {
  202. int wCRCin = 0xFFFF;
  203. int wCPoly = 0xa001;
  204. for (byte b : buffer) {
  205. wCRCin ^= ((int) b & 0x00ff);
  206. for (int j = 0; j < 8; j++) {
  207. if ((wCRCin & 0x0001) != 0) {
  208. wCRCin >>= 1;
  209. wCRCin ^= wCPoly;
  210. } else {
  211. wCRCin >>= 1;
  212. }
  213. }
  214. }
  215. return wCRCin ^= 0xffff;
  216. }
  217. /**
  218. * CRC16_DNP: Polynomial x16+x13+x12+x11+x10+x8+x6+x5+x2+1 (0x3D65), initial value 0x0000, low bit first, high bit after, result is XORIF 0xFFFF
  219. * 0xA6BC is the result of 0x3D65 bitwise reversal
  220. *
  221. * @param buffer
  222. * @return
  223. */
  224. public static int CRC16_DNP(byte[] buffer) {
  225. int wCRCin = 0x0000;
  226. int wCPoly = 0xA6BC;
  227. for (byte b : buffer) {
  228. wCRCin ^= ((int) b & 0x00ff);
  229. for (int j = 0; j < 8; j++) {
  230. if ((wCRCin & 0x0001) != 0) {
  231. wCRCin >>= 1;
  232. wCRCin ^= wCPoly;
  233. } else {
  234. wCRCin >>= 1;
  235. }
  236. }
  237. }
  238. return wCRCin ^= 0xffff;
  239. }
  240. }