// function CRC16(data) { // var len = data.length; // if (len > 0) { // var crc = 0xFFFF; // for (var i = 0; i < len; i++) { // crc = (crc ^ (data[i])); // for (var j = 0; j < 8; j++) { // crc = (crc & 1) != 0 ? ((crc >> 1) ^ 0xA001) : (crc >> 1); // } // } // var hi = ((crc & 0xFF00) >> 8); // //高位置 // var lo = (crc & 0x00FF); // //低位置 // // return [hi, lo]; // return [lo, hi]; // // 大端模式 // } // return [0, 0]; // }; function isArray(arr) { return Object.prototype.toString.call(arr) === '[object Array]'; }; // function ToCRC16(str, isReverse) { // return toString(CRC16(isArray(str) ? str : strToByte(str)), isReverse); // }; function strToByte(str) { var tmp = str.split(''), arr = []; for (var i = 0, c = tmp.length; i < c; i++) { var j = encodeURI(tmp[i]); if (j.length == 1) { arr.push(j.charCodeAt()); } else { var b = j.split('%'); for ( var m = 1; m < b.length; m++) { arr.push(parseInt('0x' + b[m])); } } } return arr; }; function convertChinese(str) { var tmp = str.split(''), arr = []; for (var i = 0, c = tmp.length; i < c; i++) { var s = tmp[i].charCodeAt(); if (s <= 0 || s >= 127) { arr.push(s.toString(16)); } else { arr.push(tmp[i]); } } return arr; }; function filterChinese(str) { var tmp = str.split(''), arr = []; for (var i = 0, c = tmp.length; i < c; i++) { var s = tmp[i].charCodeAt(); if (s > 0 && s < 127) { arr.push(tmp[i]); } } return arr; }; function strToHex(hex, isFilterChinese) { hex = isFilterChinese ? filterChinese(hex).join('') : convertChinese(hex).join(''); //清除所有空格 hex = hex.replace(/\s/g, ""); //若字符个数为奇数,补一个空格 hex += hex.length % 2 != 0 ? " " : ""; var c = hex.length / 2, arr = []; for (var i = 0; i < c; i++) { arr.push(parseInt(hex.substr(i * 2, 2), 16)); } return arr; }; function padLeft(s, w, pc) { if (pc == undefined) { pc = '0'; } for (var i = 0, c = w - s.length; i < c; i++) { s = pc + s; } return s; }; function toString(arr, isReverse) { if ( typeof isReverse == 'undefined') { isReverse = true; } var hi = arr[0], lo = arr[1]; return padLeft((isReverse ? hi + lo * 0x100 : hi * 0x100 + lo).toString(16).toUpperCase(), 4, '0'); }; function CRC16(data) { var len = data.length; if (len > 0) { var crc = 0xFFFF; for ( var i = 0; i < len; i++) { crc = (crc ^ (data[i])); for (var j = 0; j < 8; j++) { crc = (crc & 1) != 0 ? ((crc >> 1) ^ 0xA001) : (crc >> 1); } } var hi = ((crc & 0xFF00) >> 8); //高位置 var lo = (crc & 0x00FF); //低位置 // return [hi, lo]; return [lo, hi]; // 大端模式 } return [0, 0]; }; function ToCRC16(str, isReverse) { return toString(CRC16(isArray(str) ? str : strToByte(str)), isReverse); }; function ToModbusCRC16(str, isReverse) { return toString(CRC16(isArray(str) ? str : strToHex(str)), isReverse); }; /** * 给命令增加CRC 16进制 * * @param hex * @return 16进制 */ function getCRCCmd(hex) { var hexTemp = hex; if (hex.toUpperCase().startsWith("0X")) { hexTemp = hex.substr(4); } else if (hex.toUpperCase().startsWith("AA")) { hexTemp = hex.substr(2); } return hex + getCRCStr(hexTemp); } /** * 获取CRC 16进制 * * @param data * @return */ function getCRCStr(data) { return ToModbusCRC16(data); } module.exports = { ToCRC16: ToCRC16, ToModbusCRC16: ToModbusCRC16, getCRCCmd: getCRCCmd }