262 lines
7.4 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.

import {md5} from 'js-md5'
import crc from 'crc'
// 周数组转换
export function convertWeekdaysToNumber(weekDay) {
let weekStr = '00000000'
// eslint-disable-next-line no-restricted-syntax
for (const day of weekDay) {
const index = day % 7
weekStr = weekStr.substring(0, index) + '1' + weekStr.substring(index + 1)
}
// 倒序 weekStr
weekStr = weekStr.split('').reverse().join('')
return parseInt(weekStr, 2)
}
// 时间戳转二进制
export function timestampToArray(timestamp) {
const array = new Uint8Array(4)
array[0] = (timestamp & 0xff000000) >> 24
array[1] = (timestamp & 0xff0000) >> 16
array[2] = (timestamp & 0xff00) >> 8
array[3] = timestamp & 0xff
return array
}
// 时分字符串转二进制
export function parseTimeToList(timeString) {
let timeList = [0, 0, 0, 0]
if (timeString.includes(':')) {
let timeParts = timeString.split(':')
timeList[2] = parseInt(timeParts[0], 10)
timeList[3] = parseInt(timeParts[1], 10)
}
return new Uint8Array(timeList)
}
// md5加密
export function md5Encrypt(text, token, key) {
const length = text.length + 4 + 16
const md5Array = new Uint8Array(length)
for (let i = 0; i < text.length; i++) {
md5Array[i] = text.charCodeAt(i)
}
md5Array.set(token, text.length)
md5Array.set(key, text.length + 4)
const md5Text = md5(md5Array)
return new Uint8Array(md5Text.match(/.{1,2}/g).map(byte => parseInt(byte, 16)))
}
// 生成包尾 头部数据+内容数据
export function createPackageEnd(headArray, contentArray) {
// 拼接头部和内容
let mergerArray = new Uint8Array(headArray.length + contentArray.length)
mergerArray.set(headArray)
mergerArray.set(contentArray, headArray.length)
// crc加密
const crcResult = crc.crc16kermit(mergerArray)
// 拼接crc
let newArray = new Uint8Array(mergerArray.length + 2)
newArray.set(mergerArray)
newArray.set([crcResult / 256, crcResult % 256], mergerArray.length)
return newArray
}
// 二进制转时间戳
export function arrayToTimestamp(array) {
const timestamp = (array[0] << 24) | (array[1] << 16) | (array[2] << 8) | array[3]
return timestamp >>> 0
}
// 二进制转字符串
export function uint8ArrayToString(uint8Array) {
let str = ''
for (let i = 0; i < uint8Array.length; i++) {
if (uint8Array[i] !== 0) {
str += String.fromCharCode(uint8Array[i])
}
}
return str
}
// 去除特征值尾部0
export function removeTrailingZeros(data) {
const featureCount = data[0]
let currentIndex = 1
for (let i = 0; i < featureCount; i++) {
const length = data[currentIndex + 1]
currentIndex += 2 + length
}
return data.slice(0, currentIndex)
}
/**
* 将分钟时间转换为两个字节的数组
* @param minutes
* @returns {(number|number)[]}
*/
export function convertTimeToBytes(minutes) {
return [
Math.floor(minutes / 256), // 高字节
minutes % 256 // 低字节
];
}
/**
* 二进制字符串转换为十进制数字数组
* 例如 '0111110' 会被转换为 [1, 2, 3, 4, 5](表示周一到周五)
* @param weekdayBit
* @returns {*[]}
*/
export function convertWeekdayBitToArray(weekdayBit) {
const weekdays = [];
const bits = weekdayBit.split('');
bits.forEach((bit, index) => {
if (bit === '1') {
weekdays.push(index);
}
});
return weekdays;
}
/**
* 十进制数字数组转为二进制字符串
* 例如 将 [1,2,3,4,5] 转换回 '0111110'(表示周一到周五)
* @param {number[]} weekdays - 周几数组1-7 分别代表周一到周日
* @returns {string} - 7位二进制字符串从右到左分别代表周一到周日
*/
export function convertWeekdayArrayToBit(weekdays) {
const bits = new Array(7).fill('0');
weekdays.forEach(day => {
if (day >= 1 && day <= 7) {
// 将1-7转换为0-6的数组索引
const index = day === 7 ? 0 : day - 1;
bits[index] = '1';
}
});
return bits.join('');
}
/**
* 用于判断时间戳是否是秒级别的,如果是的话则补充到毫秒级别
* @param timestamp 时间戳
* @returns {number|*}
* @private
*/
export function _convertToMilliseconds(timestamp) {
if (!timestamp) return timestamp;
return timestamp.toString().length === 10 ? timestamp * 1000 : timestamp;
}
/**
* 检查并返回具体哪个参数为空
* @param {Object} params - 参数对象
* @param {Array<string>} requiredFields - 必填字段列表
* @returns {string | null} - 如果有字段为空则返回错误消息否则返回null
*/
export function checkRequiredFields(params, requiredFields) {
for (let field of requiredFields) {
if (params[field] === undefined || params[field] === null) {
return `${field} 不能为空`;
}
}
return null;
}
/**
* 转换解析wifi列表数据
* @param data
* @returns {{status: *, numberOfSsid: *, wifiList: *[]}}
*/
export function parseWifiList(data) {
// data: Array or Uint8Array
// 跳过前两位命令码
const status = data[2];
const numberOfSsid = data[3];
const wifiList = [];
let offset = 4;
for (let i = 0; i < numberOfSsid; i++) {
// 取32字节SSID
const ssidBytes = data.slice(offset, offset + 32);
// 用自定义函数转字符串并去除末尾0
const ssid = _bytesToString(ssidBytes).trim();
offset += 32;
// 取rssi
let rssi = data[offset];
// 通常rssi是无符号byte需转为有符号
if (rssi > 127) rssi = rssi - 256;
offset += 1;
// 过滤空名
if (ssid) {
wifiList.push({ssid, rssi});
}
}
return {status, numberOfSsid, wifiList};
}
function _bytesToString(bytes) {
// 只适用于ASCII和UTF-8无多字节字符的场景
let str = '';
for (let i = 0; i < bytes.length; i++) {
if (bytes[i] === 0) break; // 截断0
str += String.fromCharCode(bytes[i]);
}
return str;
}
// 解析decrypted中的json数据返回对象
export function parseNetworkJsonFromDecrypted(decrypted) {
let peerId, wifiName, secretKey, deviceMac, networkMac;
try {
const secretKeyJsonLength = (decrypted[4] << 8) + decrypted[3];
const secretKeyList = decrypted.slice(5, 5 + secretKeyJsonLength);
let result;
if (typeof TextDecoder !== 'undefined') {
result = new TextDecoder('utf-8').decode(secretKeyList);
} else {
// 兼容性处理
result = uint8ArrayToString(secretKeyList);
}
const jsonMap = JSON.parse(result);
peerId = jsonMap.peerId;
wifiName = jsonMap.wifiName;
secretKey = jsonMap.secretKey;
deviceMac = jsonMap.deviceMac;
networkMac = jsonMap.networkMac;
console.log('解析配网信息:', jsonMap);
} catch (e) {
console.error('解析配网信息失败:', e);
}
return { peerId, wifiName, secretKey, deviceMac, networkMac };
}
/**
* 生成随机长度字符串
* @param length
* @returns {string}
*/
export function generateRandomString(length) {
const chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
let result = '';
for (let i = 0; i < length; i++) {
result += chars[Math.floor(Math.random() * chars.length)];
}
return result;
}