fastbee/yack-mini/miniprogram/utils/hex.js
2026-09-05 10:19:07 +08:00

119 lines
2.6 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/**
* 十六进制工具函数
*/
/**
* 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<number>} 字节数组
*/
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<number>} 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,
};