/** * 十六进制工具函数 */ /** * ArrayBuffer 转十六进制字符串 * @param {ArrayBuffer} buffer - ArrayBuffer 数据 * @returns {string} 十六进制字符串(大写) */ function arrayBufferToHex(buffer) { const hexArr = Array.prototype.map.call( new Uint8Array(buffer), function (byte) { return ('0' + byte.toString(16)).slice(-2); } ); return hexArr.join('').toUpperCase(); } /** * 十六进制字符串转 ArrayBuffer * @param {string} hex - 十六进制字符串 * @returns {ArrayBuffer} ArrayBuffer 数据 */ function hexToArrayBuffer(hex) { // 去除空格和换行 hex = hex.replace(/\s+/g, ''); // 确保长度为偶数 if (hex.length % 2 !== 0) { hex = '0' + hex; } const length = hex.length / 2; const buffer = new ArrayBuffer(length); const dataView = new DataView(buffer); for (let i = 0; i < length; i++) { const byte = parseInt(hex.substr(i * 2, 2), 16); dataView.setUint8(i, byte); } return buffer; } /** * 十六进制字符串转字节数组 * @param {string} hex - 十六进制字符串 * @returns {Array} 字节数组 */ function hexToBytes(hex) { hex = hex.replace(/\s+/g, ''); const bytes = []; for (let i = 0; i < hex.length; i += 2) { bytes.push(parseInt(hex.substr(i, 2), 16)); } return bytes; } /** * 字节数组转十六进制字符串 * @param {Array} bytes - 字节数组 * @returns {string} 十六进制字符串 */ function bytesToHex(bytes) { return bytes .map(b => ('0' + b.toString(16)).slice(-2)) .join('') .toUpperCase(); } /** * CRC16 校验(Modbus RTU) * @param {string} hex - 十六进制字符串(不含 CRC) * @returns {string} CRC16 校验码(4位十六进制) */ function crc16(hex) { const bytes = hexToBytes(hex); let crc = 0xFFFF; for (let i = 0; i < bytes.length; i++) { crc ^= bytes[i]; for (let j = 0; j < 8; j++) { if (crc & 0x0001) { crc = (crc >> 1) ^ 0xA001; } else { crc = crc >> 1; } } } // 返回低位在前,高位在后 const low = (crc & 0xFF).toString(16).padStart(2, '0'); const high = ((crc >> 8) & 0xFF).toString(16).padStart(2, '0'); return (low + high).toUpperCase(); } /** * 验证 CRC16 校验码 * @param {string} hex - 完整的十六进制字符串(含 CRC) * @returns {boolean} 校验是否通过 */ function verifyCrc16(hex) { if (hex.length < 4) return false; const data = hex.slice(0, -4); const crc = hex.slice(-4); return crc16(data) === crc; } module.exports = { arrayBufferToHex, hexToArrayBuffer, hexToBytes, bytesToHex, crc16, verifyCrc16, };