crc.js 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166
  1. // function CRC16(data) {
  2. // var len = data.length;
  3. // if (len > 0) {
  4. // var crc = 0xFFFF;
  5. // for (var i = 0; i < len; i++) {
  6. // crc = (crc ^ (data[i]));
  7. // for (var j = 0; j < 8; j++) {
  8. // crc = (crc & 1) != 0 ? ((crc >> 1) ^ 0xA001) : (crc >> 1);
  9. // }
  10. // }
  11. // var hi = ((crc & 0xFF00) >> 8);
  12. // //高位置
  13. // var lo = (crc & 0x00FF);
  14. // //低位置
  15. // // return [hi, lo];
  16. // return [lo, hi];
  17. // // 大端模式
  18. // }
  19. // return [0, 0];
  20. // };
  21. function isArray(arr) {
  22. return Object.prototype.toString.call(arr) === '[object Array]';
  23. };
  24. // function ToCRC16(str, isReverse) {
  25. // return toString(CRC16(isArray(str) ? str : strToByte(str)), isReverse);
  26. // };
  27. function strToByte(str) {
  28. var tmp = str.split(''),
  29. arr = [];
  30. for (var i = 0, c = tmp.length; i < c; i++) {
  31. var j = encodeURI(tmp[i]);
  32. if (j.length == 1) {
  33. arr.push(j.charCodeAt());
  34. } else {
  35. var b = j.split('%');
  36. for (
  37. var m = 1; m < b.length; m++) {
  38. arr.push(parseInt('0x' + b[m]));
  39. }
  40. }
  41. }
  42. return arr;
  43. };
  44. function convertChinese(str) {
  45. var tmp = str.split(''),
  46. arr = [];
  47. for (var i = 0, c = tmp.length; i < c; i++) {
  48. var s = tmp[i].charCodeAt();
  49. if (s <= 0 || s >= 127) {
  50. arr.push(s.toString(16));
  51. } else {
  52. arr.push(tmp[i]);
  53. }
  54. }
  55. return arr;
  56. };
  57. function filterChinese(str) {
  58. var tmp = str.split(''),
  59. arr = [];
  60. for (var i = 0, c = tmp.length; i < c; i++) {
  61. var s = tmp[i].charCodeAt();
  62. if (s > 0 && s < 127) {
  63. arr.push(tmp[i]);
  64. }
  65. }
  66. return arr;
  67. };
  68. function strToHex(hex, isFilterChinese) {
  69. hex = isFilterChinese ? filterChinese(hex).join('') : convertChinese(hex).join('');
  70. //清除所有空格
  71. hex = hex.replace(/\s/g, "");
  72. //若字符个数为奇数,补一个空格
  73. hex += hex.length % 2 != 0 ? " " : "";
  74. var c = hex.length / 2,
  75. arr = [];
  76. for (var i = 0; i < c; i++) {
  77. arr.push(parseInt(hex.substr(i * 2, 2), 16));
  78. }
  79. return arr;
  80. };
  81. function padLeft(s, w, pc) {
  82. if (pc == undefined) {
  83. pc = '0';
  84. }
  85. for (var i = 0, c = w - s.length; i < c; i++) {
  86. s = pc + s;
  87. }
  88. return s;
  89. };
  90. function toString(arr, isReverse) {
  91. if (
  92. typeof isReverse == 'undefined') {
  93. isReverse = true;
  94. }
  95. var hi = arr[0],
  96. lo = arr[1];
  97. return padLeft((isReverse ? hi + lo * 0x100 : hi * 0x100 + lo).toString(16).toUpperCase(), 4, '0');
  98. };
  99. function CRC16(data) {
  100. var len = data.length;
  101. if (len > 0) {
  102. var crc = 0xFFFF;
  103. for (
  104. var i = 0; i < len; i++) {
  105. crc = (crc ^ (data[i]));
  106. for (var j = 0; j < 8; j++) {
  107. crc = (crc & 1) != 0 ? ((crc >> 1) ^ 0xA001) : (crc >> 1);
  108. }
  109. }
  110. var hi = ((crc & 0xFF00) >> 8);
  111. //高位置
  112. var lo = (crc & 0x00FF);
  113. //低位置
  114. // return [hi, lo];
  115. return [lo, hi];
  116. // 大端模式
  117. }
  118. return [0, 0];
  119. };
  120. function ToCRC16(str, isReverse) {
  121. return toString(CRC16(isArray(str) ? str : strToByte(str)), isReverse);
  122. };
  123. function ToModbusCRC16(str, isReverse) {
  124. return toString(CRC16(isArray(str) ? str : strToHex(str)), isReverse);
  125. };
  126. /**
  127. * 给命令增加CRC 16进制
  128. *
  129. * @param hex
  130. * @return 16进制
  131. */
  132. function getCRCCmd(hex) {
  133. var hexTemp = hex;
  134. if (hex.toUpperCase().startsWith("0X")) {
  135. hexTemp = hex.substr(4);
  136. } else
  137. if (hex.toUpperCase().startsWith("AA")) {
  138. hexTemp = hex.substr(2);
  139. }
  140. return hex + getCRCStr(hexTemp);
  141. }
  142. /**
  143. * 获取CRC 16进制
  144. *
  145. * @param data
  146. * @return
  147. */
  148. function getCRCStr(data) {
  149. return ToModbusCRC16(data);
  150. }
  151. module.exports = {
  152. ToCRC16: ToCRC16,
  153. ToModbusCRC16: ToModbusCRC16,
  154. getCRCCmd: getCRCCmd
  155. }