@iot9x.com/ipc-utils
Version:
九星云、九星小程序、九星配置工具所共用的库方法
486 lines (485 loc) • 19.3 kB
JavaScript
;
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;