UNPKG

@iot9x.com/ipc-utils

Version:

九星云、九星小程序、九星配置工具所共用的库方法

486 lines (485 loc) 19.3 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.Hex = void 0; const constant_1 = require("./constant"); const ieee754 = require("ieee754"); const convert_1 = require("./convert"); class Hex { /** * 十六进制字符串反转 * @description "BB AA" --> "AA BB" * @param hexStr 十六进制字符串 * @returns 转换后的十六进制字符串 */ static reverseBA(hexStr) { return hexStr.match(/\w{2}/g).reverse().join(''); } /** * 十六进制字符串反转 * @description "CC DD AA BB" --> "AA BB CC DD" * @param hexStr 十六进制字符串 * @returns 转换后的十六进制字符串 */ static reverseCDAB(hexStr) { return hexStr.slice(4) + hexStr.slice(0, 4); } /** * 十六进制字符串反转 * @description "BB AA DD CC" --> "AA BB CC DD" * @param hexStr 十六进制字符串 * @returns 转换后的十六进制字符串 */ static reverseBADC(hexStr) { return Hex.reverseBA(hexStr.slice(0, 4)) + Hex.reverseBA(hexStr.slice(4)); } /** * 十六进制字符串反转 * @description "DD CC BB AA" --> "AA BB CC DD" * @param hexStr 十六进制字符串 * @returns 转换后的十六进制字符串 */ static reverseDCBA(hexStr) { return Hex.reverseBA(hexStr); } /** * 十六进制字符串反转 * @description "GG HH EE FF CC DD AA BB" --> "AA BB CC DD EE FF GG HH" * @param hexStr 十六进制字符串 * @returns 转换后的十六进制字符串 */ static reverseGHEFCDAB(hexStr) { return Hex.reverseCDAB(hexStr.slice(8)) + Hex.reverseCDAB(hexStr.slice(0, 8)); } /** * 十六进制字符串反转 * @description "BB AA DD CC FF EE HH GG" --> "AA BB CC DD EE FF GG HH" * @param hexStr 十六进制字符串 * @returns 转换后的十六进制字符串 */ static reverseBADCFEHG(hexStr) { return Hex.reverseBADC(hexStr.slice(0, 8)) + Hex.reverseBADC(hexStr.slice(8)); } /** * 十六进制字符串反转 * @description "HH GG FF EE DD CC BB AA" --> "AA BB CC DD EE FF GG HH" * @param hexStr 十六进制字符串 * @returns 转换后的十六进制字符串 */ static reverseHGFEDCBA(hexStr) { return Hex.reverseBA(hexStr); } /** * 将十六进制字符串转换成Int16数值 * @description 'FFE9' -> -23 * @param hexStr 十六进制编码字符串 * @param i16Encode 编码格式 * @returns 转换结果 */ static toInt16(hexStr, i16Encode) { if (hexStr.length !== 4) throw new Error(`hex数据${hexStr}长度不正确,无法转换成Int16格式`); const data = i16Encode === constant_1.I16Encode.AB ? hexStr : Hex.reverseBA(hexStr); const raw = parseInt(data, 16); return raw > 0x7fff ? raw - Math.pow(2, 16) : raw; } /** * 将Int16数值转换成十六进制字符串 * @description -23 -> 'FFE9' * @param data 数值 * @param i16Encode 编码格式 * @returns 十六进制字符串 */ static fromInt16(data, i16Encode) { if (data < -0x8000 || data > 0x7fff) throw new Error(`数据值${data}超出Int16的范围`); // * [-32768,32767] const value = data >= 0 ? data : Math.pow(2, 16) + data; // ! 这个地方是精华,后续看看是否可以位运算处理 const hexStr = value.toString(16).padStart(4, '0'); return i16Encode === constant_1.I16Encode.AB ? hexStr : Hex.reverseBA(hexStr); } /** * 将十六进制字符串转换成Uint16 * @description '0017' -> 23 * @param hexStr 十六进制编码字符串 * @param i16Encode 编码格式 * @returns 转换结果 */ static toUInt16(hexStr, i16Encode) { if (hexStr.length !== 4) throw new Error(`hex数据${hexStr}长度不正确,无法转换成UInt16格式`); const data = i16Encode === constant_1.I16Encode.AB ? hexStr : Hex.reverseBA(hexStr); return parseInt(data, 16); } /** * 将UInt16数值转换成十六进制字符串 * @description 23 -> '0017' * @param data 数值 * @param i16Encode 编码格式 * @returns 十六进制字符串 */ static fromUInt16(data, i16Encode) { if (data < 0 || data > 0xffff) throw new Error(`数据值${data}超出UInt16的范围`); // * [0,65535] const hexStr = data.toString(16).padStart(4, '0'); return i16Encode === constant_1.I16Encode.AB ? hexStr : Hex.reverseBA(hexStr); } /** * 将十六进制字符串转换成Int32数值 * @description 'FFFFFFE9' -> -23 * @param hexStr 十六进制编码字符串 * @param i16Encode 编码格式 * @returns 转换结果 */ static toInt32(hexStr, i32Encode) { if (hexStr.length !== 8) throw new Error(`hex数据${hexStr}长度不正确,无法转换成Int16格式`); switch (i32Encode) { case constant_1.I32Encode.ABCD: var data = hexStr; break; case constant_1.I32Encode.BADC: var data = Hex.reverseBADC(hexStr); break; case constant_1.I32Encode.CDAB: var data = Hex.reverseCDAB(hexStr); break; case constant_1.I32Encode.DCBA: var data = Hex.reverseDCBA(hexStr); break; default: throw new Error('未知32位整型编码' + i32Encode); } const raw = parseInt(data, 16); return raw > 0x7fffffff ? raw - Math.pow(2, 32) : raw; } /** * 将Int32数值转换成十六进制字符串 * @description -23 -> 'FFFFFFE9' * @param data 数值 * @param i16Encode 编码格式 * @returns 十六进制字符串 */ static fromInt32(data, i32Encode) { if (data < -0x80000000 || data > 0x7fffffff) throw new Error(`数据值${data}超出Int32的范围`); const value = data >= 0 ? data : Math.pow(2, 32) + data; // ! 这个地方是精华,后续看看是否可以位运算处理 const hexStr = value.toString(16).padStart(8, '0'); switch (i32Encode) { case constant_1.I32Encode.ABCD: return hexStr; case constant_1.I32Encode.BADC: return Hex.reverseBADC(hexStr); case constant_1.I32Encode.CDAB: return Hex.reverseCDAB(hexStr); case constant_1.I32Encode.DCBA: return Hex.reverseDCBA(hexStr); default: throw new Error('未知32位整型编码' + i32Encode); } } /** * 将十六进制字符串转换成UInt32 * @description '00 00 00 17' -> 23 * @param hexStr 十六进制编码字符串 * @param i16Encode 编码格式 * @returns 转换结果 */ static toUInt32(hexStr, i32Encode) { if (hexStr.length !== 8) throw new Error(`hex数据${hexStr}长度不正确,无法转换成UInt32格式`); switch (i32Encode) { case constant_1.I32Encode.ABCD: var data = hexStr; break; case constant_1.I32Encode.BADC: var data = Hex.reverseBADC(hexStr); break; case constant_1.I32Encode.CDAB: var data = Hex.reverseCDAB(hexStr); break; case constant_1.I32Encode.DCBA: var data = Hex.reverseDCBA(hexStr); break; default: throw new Error('未知32位整型编码' + i32Encode); } return parseInt(data, 16); } /** * 将UInt32数值转换成十六进制字符串 * @description 23 -> '00 00 00 17' * @param data 数值 * @param i16Encode 编码格式 * @returns 十六进制字符串 */ static fromUInt32(data, i32Encode) { if (data < 0 || data > 0xffffffff) throw new Error(`数据值${data}超出UInt32的范围`); // * [0,2^32-1] const hexStr = data.toString(16).padStart(8, '0'); switch (i32Encode) { case constant_1.I32Encode.ABCD: return hexStr; case constant_1.I32Encode.BADC: return Hex.reverseBADC(hexStr); case constant_1.I32Encode.CDAB: return Hex.reverseCDAB(hexStr); case constant_1.I32Encode.DCBA: return Hex.reverseDCBA(hexStr); default: throw new Error('未知32位整型编码' + i32Encode); } } /** * 将十六进制字符串转换成Int64数值 * @description 'FFFFFFFFFFFFFFE9' -> -23 * @see https://docs.iot9x.com/docs/js/上位机工具库/Modbus/附录/精度问题 * @param hexStr 十六进制编码字符串 * @param i16Encode 编码格式 * @returns 转换结果 */ static toInt64(hexStr, i64Encode) { if (hexStr.length !== 16) throw new Error(`hex数据${hexStr}长度不正确,无法转换成Int64格式`); switch (i64Encode) { case constant_1.I64Encode.ABCDEFGH: var data = hexStr; break; case constant_1.I64Encode.BADCFEHG: var data = Hex.reverseBADCFEHG(hexStr); break; case constant_1.I64Encode.GHEFCDAB: var data = Hex.reverseGHEFCDAB(hexStr); break; case constant_1.I64Encode.HGFEDCBA: var data = Hex.reverseHGFEDCBA(hexStr); break; default: throw new Error('未知64位整型编码' + i64Encode); } const prefix = data.slice(0, 2).toUpperCase(); data = data.slice(2); switch (prefix) { case '00': // * 正数 if (data.charAt(0) !== '0' && data.charAt(0) !== '1') throw new Error(`hex数据${hexStr}超越JS安全值`); return parseInt(data, 16); case 'FF': // * 负数 if (data.charAt(0).toUpperCase() !== 'F' && data.charAt(0).toUpperCase() !== 'E') throw new Error(`hex数据${hexStr}超越JS安全值`); switch (data.charAt(0).toUpperCase()) { case 'F': return parseInt(data.slice(1), 16) - Math.pow(2, 52); case 'E': return parseInt(data.slice(1), 16) - 2 * Math.pow(2, 52); default: throw new Error(`hex数据${hexStr}超越JS安全值`); } default: throw new Error(`hex数据${hexStr}超越JS安全值`); } } /** * 将Int64数值转换成十六进制字符串 * @description -23 -> 'FFFFFFFFFFFFFFE9' * @see https://docs.iot9x.com/docs/js/上位机工具库/Modbus/附录/精度问题 * @param data 数值 * @param i16Encode 编码格式 * @returns 十六进制字符串 */ static fromInt64(data, i64Encode) { if (data < Number.MIN_SAFE_INTEGER || data > Number.MAX_SAFE_INTEGER) throw new Error(`数据值${data}超出JS安全值范围`); if (data >= 0) var hexStr = data.toString(16).padStart(16, '0'); else if (data > -(Math.pow(2, 52))) var hexStr = (Math.pow(2, 52) + data).toString(16).padStart(16, 'f'); else var hexStr = 'ffe' + (2 * Math.pow(2, 52) + data).toString(16).padStart(13, 'f'); switch (i64Encode) { case constant_1.I64Encode.ABCDEFGH: return hexStr; case constant_1.I64Encode.BADCFEHG: return Hex.reverseBADCFEHG(hexStr); case constant_1.I64Encode.GHEFCDAB: return Hex.reverseGHEFCDAB(hexStr); case constant_1.I64Encode.HGFEDCBA: return Hex.reverseHGFEDCBA(hexStr); default: throw new Error('未知64位整型编码' + i64Encode); } } /** * 将十六进制字符串转换成UInt64数值 * @description '0000000000000017' -> 23 * @see https://docs.iot9x.com/docs/js/上位机工具库/Modbus/附录/精度问题 * @param hexStr 十六进制编码字符串 * @param i16Encode 编码格式 * @returns 转换结果 */ static toUInt64(hexStr, i64Encode) { if (hexStr.length !== 16) throw new Error(`hex数据${hexStr}长度不正确,无法转换成Int64格式`); switch (i64Encode) { case constant_1.I64Encode.ABCDEFGH: var data = hexStr; break; case constant_1.I64Encode.BADCFEHG: var data = Hex.reverseBADCFEHG(hexStr); break; case constant_1.I64Encode.GHEFCDAB: var data = Hex.reverseGHEFCDAB(hexStr); break; case constant_1.I64Encode.HGFEDCBA: var data = Hex.reverseHGFEDCBA(hexStr); break; default: throw new Error('未知64位整型编码' + i64Encode); } if (data.slice(0, 2) !== '00') throw new Error(`hex数据${hexStr}超越JS安全值`); if (data.slice(2, 3) !== '0' && data.slice(2, 3) !== '1') throw new Error(`hex数据${hexStr}超越JS安全值`); return parseInt(data, 16); } /** * 将UInt32数值转换成十六进制字符串 * @description 23 -> '0000000000000017' * @see https://docs.iot9x.com/docs/js/上位机工具库/Modbus/附录/精度问题 * @param data 数值 * @param i16Encode 编码格式 * @returns 十六进制字符串 */ static fromUInt64(data, i64Encode) { if (data < 0 || data > Number.MAX_SAFE_INTEGER) throw new Error(`数据值${data}超出JS安全值范围`); const hexStr = data.toString(16).padStart(16, '0'); switch (i64Encode) { case constant_1.I64Encode.ABCDEFGH: return hexStr; case constant_1.I64Encode.BADCFEHG: return Hex.reverseBADCFEHG(hexStr); case constant_1.I64Encode.GHEFCDAB: return Hex.reverseGHEFCDAB(hexStr); case constant_1.I64Encode.HGFEDCBA: return Hex.reverseHGFEDCBA(hexStr); default: throw new Error('未知64位整型编码' + i64Encode); } } /** * 将十六进制字符串转换成Float数值 * @description '40133333' -> 2.2999999523162na84 * @param hexStr 十六进制编码字符串 * @param f32Encode 编码格式 * @returns 转换结果 */ static toFloat(hexStr, f32Encode) { if (hexStr.length !== 8) throw new Error(`hex数据${hexStr}长度不正确,无法转换成Float格式`); switch (f32Encode) { case constant_1.F32Encode.ABCD: var data = hexStr; break; case constant_1.F32Encode.BADC: var data = Hex.reverseBADC(hexStr); break; case constant_1.F32Encode.CDAB: var data = Hex.reverseCDAB(hexStr); break; case constant_1.F32Encode.DCBA: var data = Hex.reverseDCBA(hexStr); break; default: throw new Error('未知Float类型编码' + f32Encode); } const buffer = new Uint8Array(data .match(/\w/g) .join('') .match(/\w{2}/g) .map((byteHex) => parseInt(byteHex, 16))); return ieee754.read(buffer, 0, false, 23, 4); } /** * 将Float数值转换成十六进制字符串 * @description 123.456 -> '42f6e979' * @see https://www.virtualbing.fun/#/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/JavaScript/%E5%AE%9E%E8%B7%B5%E7%A7%AF%E7%B4%AF/IEEE754/README * @param data 数值 * @param f32Encode 编码格式 * @returns 十六进制字符串 */ static fromFloat(data, f32Encode) { const buffer = new Uint8Array(4); ieee754.write(buffer, data, 0, false, 23, 4); const hexStr = convert_1.Convert.uint8ArrayToHexStr(buffer); switch (f32Encode) { case constant_1.F32Encode.ABCD: return hexStr; case constant_1.F32Encode.BADC: return Hex.reverseBADC(hexStr); case constant_1.F32Encode.CDAB: return Hex.reverseCDAB(hexStr); case constant_1.F32Encode.DCBA: return Hex.reverseDCBA(hexStr); default: throw new Error('未知Float编码' + f32Encode); } } /** * 将十六进制字符串转换成Double数值 * @description '405edd2f1a9fbe77' -> 123.456 * @param hexStr 十六进制编码字符串 * @param f64Encode 编码格式 * @returns 转换结果 */ static toDouble(hexStr, f64Encode) { if (hexStr.length !== 16) throw new Error(`hex数据${hexStr}长度不正确,无法转换成Double格式`); switch (f64Encode) { case constant_1.F64Encode.ABCDEFGH: var data = hexStr; break; case constant_1.F64Encode.BADCFEHG: var data = Hex.reverseBADCFEHG(hexStr); break; case constant_1.F64Encode.GHEFCDAB: var data = Hex.reverseGHEFCDAB(hexStr); break; case constant_1.F64Encode.HGFEDCBA: var data = Hex.reverseHGFEDCBA(hexStr); break; default: throw new Error('未知Double类型编码' + f64Encode); } const buffer = new Uint8Array(data .match(/\w/g) .join('') .match(/\w{2}/g) .map((byteHex) => parseInt(byteHex, 16))); return ieee754.read(buffer, 0, false, 52, 8); } /** * 将Double数值转换成十六进制字符串 * @description 123.456 -> '405edd2f1a9fbe77' * @see https://www.virtualbing.fun/#/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/JavaScript/%E5%AE%9E%E8%B7%B5%E7%A7%AF%E7%B4%AF/IEEE754/README * @param data 数值 * @param f64Encode 编码格式 * @returns 十六进制字符串 */ static fromDouble(data, f64Encode) { const buffer = new Uint8Array(8); ieee754.write(buffer, data, 0, false, 52, 8); const hexStr = convert_1.Convert.uint8ArrayToHexStr(buffer); switch (f64Encode) { case constant_1.F64Encode.ABCDEFGH: return hexStr; case constant_1.F64Encode.BADCFEHG: return Hex.reverseBADCFEHG(hexStr); case constant_1.F64Encode.GHEFCDAB: return Hex.reverseGHEFCDAB(hexStr); case constant_1.F64Encode.HGFEDCBA: return Hex.reverseHGFEDCBA(hexStr); default: throw new Error('未知Double编码' + f64Encode); } } } exports.Hex = Hex;