You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.28 17:39:01