JavaScript如何实现整数与Uint8Array互相转换的通用函数
实现方案
核心逻辑
- 编码阶段:先计算存储目标整数所需的最小字节数,将字节数存入结果数组的第一个字节,随后按大端序(高位在前)将整数的各个字节存入后续位置
- 解码阶段:先读取数组第一个字节得到整数占用的字节数n,随后读取后续n个字节,通过位运算移位拼接还原原始整数
代码实现
整数编码函数
/** * 将正整数编码为带长度标识的Uint8Array * @param {number} num 要编码的正整数,默认最大支持32位无符号整数(0 ~ 4294967295) * @returns {Uint8Array} 编码后的数组,第一个字节为整数占用的字节数,后续为实际数值字节 */ function encodeIntToUint8(num) { if (num < 0 || !Number.isInteger(num)) { throw new Error('输入必须为非负整数'); } if (num > 0xFFFFFFFF) { throw new Error('暂不支持超过32位的无符号整数'); } // 计算存储所需的最小字节数 let byteLength = 1; if (num >= 0x1000000) byteLength = 4; else if (num >= 0x10000) byteLength = 3; else if (num >= 0x100) byteLength = 2; const result = new Uint8Array(byteLength + 1); result[0] = byteLength; // 大端序写入数值字节 for (let i = 0; i < byteLength; i++) { const shift = (byteLength - 1 - i) * 8; result[i + 1] = (num >>> shift) & 0xFF; } return result; }
整数解码函数
/** * 从Uint8Array头部解码出存储的正整数 * @param {Uint8Array} arr 包含编码整数的数组,会从索引0位置开始读取 * @returns {Object} 包含解码后的数值和该编码占用的总字节数(长度标识+数值字节) */ function decodeIntFromUint8(arr) { const byteLength = arr[0]; if (byteLength < 1 || byteLength > 4) { throw new Error('不支持的整数字节长度'); } let num = 0; for (let i = 0; i < byteLength; i++) { const shift = (byteLength - 1 - i) * 8; num |= (arr[i + 1] << shift) >>> 0; } return { value: num, totalByteSize: byteLength + 1 }; }
与LZJB压缩逻辑结合的使用示例
// 压缩流程 const rawData = ...; // 待压缩的原始Uint8Array数据 const compressed = lzjb.compress(rawData); // 调用LZJB库的压缩方法 // 将原始数据长度编码后写入压缩结果头部 const lengthBuffer = encodeIntToUint8(rawData.length); const finalCompressed = new Uint8Array(lengthBuffer.length + compressed.length); finalCompressed.set(lengthBuffer, 0); finalCompressed.set(compressed, lengthBuffer.length); // 解压流程 const receivedData = ...; // 接收到的带长度标识的压缩数据 const { value: rawLength, totalByteSize } = decodeIntFromUint8(receivedData); const compressedData = receivedData.slice(totalByteSize); const decompressed = lzjb.decompress(compressedData, rawLength); // 传入读取到的原始长度完成解压
注意事项
- 上述实现默认采用大端序存储字节,编码解码两端需要保持一致
- 若需要支持更大的整数(如JS 53位安全整数),可以对应调整字节长度判断逻辑,最多支持到7个字节即可覆盖所有JS安全整数范围
内容的提问来源于stack exchange,提问作者jcubic
相关产品推荐
相关产品推荐

