import Long from './Long.js'; //const Long = require('./Long.js') //import Long from '@/static/js/Long.js' /** * short所占byte的最大位数 */ const SHORT_MAX_LENGTH = 2; /** * int所占byte的最大位数 */ const INT_MAX_LENGTH = 4; /** * float所占byte的最大位数 */ const FLOAT_MAX_LENGTH = 4; /** * long所占byte的最大位数 */ const LONG_MAX_LENGTH = 8; /** * 一位byte所能表示的最大无符号整数是255 */ const MAX_ARRAY_LENGTH = 255; /** * 两位byte所能表示的最大无符号整数是65535 */ const MAX_LARGE_ARRAY_LENGTH = 65535; const BigEndian = 0; const LittleEndian = 1; let int8 = new Int8Array(4); let int32 = new Int32Array(int8.buffer, 0, 1); let float32 = new Float32Array(int8.buffer, 0, 1); function stringToChars(_s) { // _s = _s.replace(/(^\s*)|(\s*$)/g, ""); let _r = []; for (let i = 0; i < _s.length; i++) { _r[i] = _s.charAt(i); } return _r; } /*** * byte[] 转16进制字符串 * @param src * @return */ function bytesToHexString(src) { let stringBuilder = ""; if (src == null || src.length <= 0) { return null; } for (let i = 0; i < src.length; i++) { let v = src[i] & 0xFF; let hv = Number(v).toString(16); if (hv.length < 2) { stringBuilder += "0" } stringBuilder += hv; } return stringBuilder; } /*** * byte[] 转16进制字符串[空格隔开] * @param src * @return */ function bytesToHex(src) { let stringBuilder = ""; if (src == null || src.length <= 0) { return null; } for (let i = 0; i < src.length; i++) { let v = src[i] & 0xFF; let hv = Number(v).toString(16); if (hv.length < 2) { stringBuilder.concat(0); } stringBuilder.concat(hv).concat(""); } return stringBuilder; } /** * hexString转byteArr * * @param hexString * @return */ function hexStringToBytes(hexString) { if (hexString == null || "" === hexString) { return null; } hexString = hexString.toUpperCase(); let length = hexString.length / 2; let hexChars = stringToChars(hexString); let d = [length]; for (let i = 0; i < length; i++) { let pos = i * 2; d[i] = (charToByte(hexChars[pos]) << 4 | charToByte(hexChars[pos + 1])); } return d; } /** * char to byte * @param c * @return */ function charToByte(c) { return "0123456789ABCDEF".indexOf(c); } /** * 一位byte转int【无符号】 * * @param b * @return 【0 ~ 255】 */ function byteToIntUnSigned(b) { return b & 0xFF; } /** * int 转 byte 4 * @param n * @return */ function intToBytes(n) { let b = []; b[3] = (n & 0xff); b[2] = (n >> 8 & 0xff); b[1] = (n >> 16 & 0xff); b[0] = (n >> 24 & 0xff); return b; } /** * byte 4 转 byte 1 * @param bytes * @return */ function byte4ToByte1(bytes) { let byte1 = []; byte1[0] = bytes[3]; return byte1; } /** * * @param bytes * @return */ function bytesReverse(bytes) { let b = bytes[0]; b = ~b; return b; } // ======================【通用方法】=====================================// /** * 按照指定的存储方式来依次读取byte数据 * * @param mode 存储方式 * @param src byte数组 * @param offset 从数组的第offset位开始 * @param length 长度 * @return */ function readBytes(mode, src, offset, length) { let value = 0; //从低位开始读 if (LittleEndian === mode) { for (let i = 0; i < length; i++) { value |= (src[offset + i] & 0xFF) << (8 * i); } } else { for (let i = 0; i < length; i++) { value |= (src[offset + length - i - 1] & 0xFF) << (8 * i); } } return value; } /** * 填充数值到byte数组中 * * @param mode 存储方式 * @param value 数值 * @param src byte数组 * @param offset 从数组的第offset位开始 * @param length 数值的长度 */ function fillValueToBytes(mode, value, src, offset, length) { if (LittleEndian === mode) { for (let i = 0; i < length; i++) { src[offset + i] = ((value >> (i * 8)) & 0xFF); } } else { for (let i = 0; i < length; i++) { src[offset + length - i - 1] = ((value >> (i * 8)) & 0xFF); } } } /** * 将值转化为byte数组 * * @param mode 存储方式 * @param value 数值 * @param length 数值的长度 */ function valueToBytes(mode, value, length) { let bytes = []; if (LittleEndian === mode) { for (let i = 0; i < length; i++) { bytes[i] = ((value >> (i * 8)) & 0xFF); } } else { for (let i = 0; i < length; i++) { bytes[length - i - 1] = ((value >> (i * 8)) & 0xFF); } } return bytes; } // ======================【byte数组<-->(无符号)short】=====================================// /** * byte数组中取short数值 * * @param mode 存储方式 * @param src byte数组 * @param offset 从数组的第offset位开始 * @param length 长度 * @return short 数值 */ function bytesToShort(mode, src, offset, length) { if (length < 1 || length > SHORT_MAX_LENGTH) { //纠正错误的长度 length = SHORT_MAX_LENGTH; } return readBytes(mode, src, offset, length); } /** * byte数组中取short数值 * * @param mode 存储方式 * @param src byte数组 * @param offset 从数组的第offset位开始 * @return short 数值 */ // function bytesToShort(mode, src, offset) { // return readBytes(mode, src, offset, SHORT_MAX_LENGTH); // } /** * 将short填充至byte数组中 * * @param mode 存储方式 * @param value 数值 * @param src byte数组 * @param offset 从数组的第offset位开始 * @param length 长度 * @return short数值 */ function fillShortToBytes(mode, value, src, offset, length) { if (length < 1 || length > SHORT_MAX_LENGTH) { //纠正错误的长度 length = SHORT_MAX_LENGTH; } fillValueToBytes(mode, value, src, offset, length); return offset + length; } /** * 将short填充至byte数组中 * * @param mode 存储方式 * @param value 数值 * @param src byte数组 * @param offset 从数组的第offset位开始 * @return short数值 */ // function fillShortToBytes(mode, value, src, offset) { // fillValueToBytes(mode, value, src, offset, SHORT_MAX_LENGTH); // return offset + SHORT_MAX_LENGTH; // } // ======================【byte数组<-->(无符号)int】=====================================// /** * byte数组中取int数值 * * @param mode 存储方式 * @param src byte数组 * @param offset 从数组的第offset位开始 * @param length 长度 * @return short数值 */ function bytesToInt(mode, src, offset, length) { if (length < 1 || length > INT_MAX_LENGTH) { //纠正错误的长度 length = INT_MAX_LENGTH; } return readBytes(mode, src, offset, length); } /** * 将Int填充至byte数组中 * * @param mode 存储方式 * @param value 数值 * @param src byte数组 * @param offset 从数组的第offset位开始 * @param length 长度 * @return short数值 */ function fillIntToBytes(mode, value, src, offset, length) { if (length < 1 || length > INT_MAX_LENGTH) { //纠正错误的长度 length = INT_MAX_LENGTH; } fillValueToBytes(mode, value, src, offset, length); return offset + length; } // ======================【byte数组<-->(无符号)long】=====================================// /** * byte数组中取long数值 * * @param mode 存储方式 * @param src byte数组 * @param offset 从数组的第offset位开始 * @param length 长度 * @return short数值 */ function bytesToLong(mode, src, offset, length) { if (length < 1 || length > LONG_MAX_LENGTH) { //纠正错误的长度 length = LONG_MAX_LENGTH; } let value = Long.fromNumber(0); let bt = [] for (let i = 0; i < length; i++) { bt[i] = src[offset + i] } //从低位开始读 if (LittleEndian === mode) { value = Long.fromBytesLE(bt).toNumber(); } else { value = Long.fromBytesBE(bt).toNumber(); } return value; } /** * 将long填充至byte数组中 * * @param mode 存储方式 * @param value 数值 * @param src byte数组 * @param offset 从数组的第offset位开始 * @param length 长度 * @return short数值 */ function fillLongToBytes(mode, value, src, offset, length) { if (length < 1 || length > LONG_MAX_LENGTH) { //纠正错误的长度 length = LONG_MAX_LENGTH; } let bt = [] if (LittleEndian === mode) { bt = Long.fromValue(value).toBytesLE() } else { bt = Long.fromValue(value).toBytesBE() } for (let i = 0; i < length; i++) { src[offset + i] = bt[i] } return offset + length; } // ======================【byte数组<--> String】=====================================// /** * byte数组中取String数值 * * @param mode 存储方式 * @param src byte数组 * @param offset 从数组的第offset位开始 * @param length 长度 * @return String */ function bytesToString(src, offset, length) { let arr = [] for (let i = 0; i < length; i++) { let value = src[offset + i]; if (value !== 0) { arr[i] = value } } let str = '', _arr = arr; for (let i = 0; i < _arr.length; i++) { let one = _arr[i].toString(2), v = one.match(/^1+?(?=0)/); if (v && one.length === 8) { let bytesLength = v[0].length; let store = _arr[i].toString(2).slice(7 - bytesLength); for (let st = 1; st < bytesLength; st++) { store += _arr[st + i].toString(2).slice(2); } str += String.fromCharCode(parseInt(store, 2)); i += bytesLength - 1; } else { str += String.fromCharCode(_arr[i]); } } return str.trim(); } function fillStringToBytes(value, src, offset, length) { let bytes = []; let c; for (let i = 0; i < value.length; i++) { c = value.charCodeAt(i); if (c >= 0x010000 && c <= 0x10FFFF) { bytes.push(((c >> 18) & 0x07) | 0xF0); bytes.push(((c >> 12) & 0x3F) | 0x80); bytes.push(((c >> 6) & 0x3F) | 0x80); bytes.push((c & 0x3F) | 0x80); } else if (c >= 0x000800 && c <= 0x00FFFF) { bytes.push(((c >> 12) & 0x0F) | 0xE0); bytes.push(((c >> 6) & 0x3F) | 0x80); bytes.push((c & 0x3F) | 0x80); } else if (c >= 0x000080 && c <= 0x0007FF) { bytes.push(((c >> 6) & 0x1F) | 0xC0); bytes.push((c & 0x3F) | 0x80); } else { bytes.push(c & 0xFF); } } for (let i = 0; i < length; i++) { src[offset + i] = bytes[i] } return bytes; } // ======================【大小端转化】=====================================// /** * 大端值转小端 * * @param value * @param length * @return */ function bigEndianToLittleEndian(value, length) { let src = valueToBytes(BigEndian, value, length); return readBytes(LittleEndian, src, 0, length); } /** * 小端值转大端 * * @param value * @param length * @return */ function littleEndianToBigEndian(value, length) { let src = valueToBytes(LittleEndian, value, length); return readBytes(BigEndian, src, 0, length); } /** * byte 转 hex * @param b * @return */ function byteToHex(b) { let hex = Integer.toHexString(b & 0xFF); if (hex.length() < 2) { hex = "0" + hex; } return hex; } function byteToBit(a) { let temp = new byte[8]; for (let i = 7; i >= 0; i--) { temp[i] = ((a >> i) & 1); } return temp; } function bitToByte(a) { let temp = 0; for (let i = 0; i < a.length; i++) { temp = (temp | a[i] << i); } return temp; } function intBitsToFloat(i) { int32[0] = i; return float32[0]; } function floatToIntBits(f) { float32[0] = f; return int32[0]; } /////////////////////////////////////////////测试///////////////////////////////////////////////////////// //测试 61850 静态图谱文件 小端模式 let hexStr = ""; // let bytes = hexStringToBytes(hexStr); // normVersion = intBitsToFloat(bytesToInt(LittleEndian, bytes, 0, 4)) // fileVersion = intBitsToFloat(bytesToInt(LittleEndian, bytes, 4, 4)) // atlasType = bytesToShort(LittleEndian, bytes, 8, 2) // atlasTime = bytesToLong(LittleEndian, bytes, 10, 8) // testFileFlag = bytes[18] // chName = bytesToString(bytes, 19, 32) // dischargeType = bytes[51] // alarmLevel = bytes[52] // dischargeFlag = bytes[53] // dischargeTypeBability = [] // for (let i = 0, offset = 54; i < 7; i++, offset += 4) { // dischargeTypeBability[i] = intBitsToFloat(bytesToInt(LittleEndian, bytes, offset, 4)) // } // phase = bytesToInt(LittleEndian, bytes, 82, 4) // amplitude = bytesToInt(LittleEndian, bytes, 86, 4) // periodicity = bytesToInt(LittleEndian, bytes, 90, 4) // correlation50Hz = bytesToInt(LittleEndian, bytes, 94, 4) // correlation100Hz = bytesToInt(LittleEndian, bytes, 98, 4) // atlasFlag = bytes[102] // dBmUnit = bytes[103] // dBmMin = intBitsToFloat(bytesToInt(LittleEndian, bytes, 104, 4)) // dBmMax = intBitsToFloat(bytesToInt(LittleEndian, bytes, 108, 4)) // decollator = bytesToString(bytes, 112, 4) // dBmData = [] // for (let i = 0, offset = 116; i < 6400; i++, offset += 4) { // dBmData[i] = intBitsToFloat(bytesToInt(LittleEndian, bytes, offset, 4)) // } // console.log(normVersion, fileVersion, atlasType, atlasTime, testFileFlag, chName, dischargeType, alarmLevel, dischargeFlag, dischargeTypeBability, phase // , amplitude, periodicity, correlation50Hz, correlation100Hz, atlasFlag, dBmUnit, dBmMin, dBmMax, decollator, dBmData) // //转字节 // let data = [] // fillIntToBytes(LittleEndian , floatToIntBits(normVersion), data , 0 , 4) // fillIntToBytes(LittleEndian , floatToIntBits(fileVersion), data , 4 , 4) // fillShortToBytes(LittleEndian , atlasType , data, 8 , 2) // fillLongToBytes(LittleEndian , atlasTime , data , 10 , 8) // data[18] = testFileFlag // fillStringToBytes(chName , data , 19,32) // data[51] = dischargeType // data[52] = alarmLevel // data[53] = dischargeFlag // for(let i = 0 , offset = 54 ; i< 7 ; i++ ,offset+=4 ){ // fillIntToBytes(LittleEndian , floatToIntBits(dischargeTypeBability[i]), data , offset , 4) // } // fillIntToBytes(LittleEndian , phase , data , 82 , 4) // fillIntToBytes(LittleEndian , amplitude , data , 86 , 4) // fillIntToBytes(LittleEndian , periodicity , data , 90 , 4) // fillIntToBytes(LittleEndian , correlation50Hz , data , 94 , 4) // fillIntToBytes(LittleEndian , correlation100Hz , data , 98 , 4) // data[102] = atlasFlag // data[103] = dBmUnit // fillIntToBytes(LittleEndian , floatToIntBits(dBmMin), data , 104 , 4) // fillIntToBytes(LittleEndian , floatToIntBits(dBmMax), data , 108 , 4) // fillStringToBytes(decollator , data , 112,4) // for(let i = 0 , offset = 116 ; i< 6400 ; i++ ,offset+=4 ){ // fillIntToBytes(LittleEndian , floatToIntBits(dBmData[i]), data , offset , 4) // } // console.log(bytesToHexString(data) === hexStr) ///测试大端模式 let bigHexStr = "" // bytes = hexStringToBytes(bigHexStr); // normVersion = intBitsToFloat(bytesToInt(BigEndian,bytes,0,4)) // fileVersion = intBitsToFloat(bytesToInt(BigEndian,bytes,4,4)) // atlasType = bytesToShort(BigEndian,bytes,8,2) // atlasTime = bytesToLong(BigEndian , bytes , 10 , 8) // testFileFlag = bytes[18] // chName = bytesToString(bytes,19,32) // dischargeType = bytes[51] // alarmLevel = bytes[52] // dischargeFlag = bytes[53] // dischargeTypeBability = [] // for(let i = 0 , offset = 54 ; i< 7 ; i++ ,offset+=4 ){ // dischargeTypeBability[i] = intBitsToFloat(bytesToInt(BigEndian,bytes,offset,4)) // } // phase = bytesToInt(BigEndian , bytes , 82 , 4) // amplitude = bytesToInt(BigEndian , bytes , 86 , 4) // periodicity = bytesToInt(BigEndian , bytes , 90 , 4) // correlation50Hz = bytesToInt(BigEndian , bytes , 94 , 4) // correlation100Hz = bytesToInt(BigEndian , bytes , 98 , 4) // atlasFlag = bytes[102] // dBmUnit = bytes[103] // dBmMin = intBitsToFloat(bytesToInt(BigEndian,bytes,104,4)) // dBmMax = intBitsToFloat(bytesToInt(BigEndian,bytes,108,4)) // decollator = bytesToString(bytes, 112 ,4) // dBmData = [] // for(let i = 0 , offset = 116 ; i< 6400 ; i++ ,offset+=4 ){ // dBmData[i] = intBitsToFloat(bytesToInt(BigEndian,bytes,offset,4)) // } // console.log(normVersion,fileVersion,atlasType,atlasTime,testFileFlag,chName,dischargeType,alarmLevel,dischargeFlag,dischargeTypeBability,phase // ,amplitude,periodicity,correlation50Hz,correlation100Hz,atlasFlag,dBmUnit,dBmMin,dBmMax,decollator,dBmData) // //转字节 // fillIntToBytes(BigEndian , floatToIntBits(normVersion), data , 0 , 4) // fillIntToBytes(BigEndian , floatToIntBits(fileVersion), data , 4 , 4) // fillShortToBytes(BigEndian , atlasType , data, 8 , 2) // fillLongToBytes(BigEndian , atlasTime , data , 10 , 8) // data[18] = testFileFlag // fillStringToBytes(chName , data , 19,32) // data[51] = dischargeType // data[52] = alarmLevel // data[53] = dischargeFlag // for(let i = 0 , offset = 54 ; i< 7 ; i++ ,offset+=4 ){ // fillIntToBytes(BigEndian , floatToIntBits(dischargeTypeBability[i]), data , offset , 4) // } // fillIntToBytes(BigEndian , phase , data , 82 , 4) // fillIntToBytes(BigEndian , amplitude , data , 86 , 4) // fillIntToBytes(BigEndian , periodicity , data , 90 , 4) // fillIntToBytes(BigEndian , correlation50Hz , data , 94 , 4) // fillIntToBytes(BigEndian , correlation100Hz , data , 98 , 4) // data[102] = atlasFlag // data[103] = dBmUnit // fillIntToBytes(BigEndian , floatToIntBits(dBmMin), data , 104 , 4) // fillIntToBytes(BigEndian , floatToIntBits(dBmMax), data , 108 , 4) // fillStringToBytes(decollator , data , 112,4) // for(let i = 0 , offset = 116 ; i< 6400 ; i++ ,offset+=4 ){ // fillIntToBytes(BigEndian , floatToIntBits(dBmData[i]), data , offset , 4) // } // console.log(bytesToHexString(data) === bigHexStr) export { LittleEndian, BigEndian, hexStringToBytes, intBitsToFloat, bytesToShort, bytesToLong, bytesToInt, bytesToString, fillIntToBytes, fillShortToBytes, fillLongToBytes, fillStringToBytes, bytesToHexString, }