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

如何在浏览器端用JavaScript解析二进制文件?转译Python解析逻辑

二进制文件解析:从Python注释到JavaScript实现

我需要在浏览器中解析若干二进制文件,找到了一份推测可实现所需功能的Python代码,但因对Python了解不足,无法理解其逻辑。已在个人代码仓库准备了示例文件,并编写了一段支持拖拽文件的JavaScript代码尝试解析,但不确定当前方向是否正确。目前仅能从该Python文件的注释中获取此类文件的结构信息,请问如何将这些文件格式信息转化为对应的JavaScript解析操作?

我的尝试代码

HTML

<h1>Drop a file here</h1>

CSS

html,body {height: 100vh;margin: 0;}
.drag-over {background-color: #ccc;}

JavaScript

const elBody = document.body;
const dragClass = "drag-over";

const fReader = new FileReader();
fReader.onload = function (e) {
    const data = e.target.result;
    processFile(data);
};

elBody.addEventListener("dragover", (dragEvent) => {
  dragEvent.preventDefault();
  if (!elBody.classList.contains(dragClass)) {
    elBody.classList.add(dragClass);
  }
});
elBody.addEventListener("dragleave", () => {
  elBody.classList.remove(dragClass);
});
elBody.addEventListener("drop", (dropEvent) => {
  dropEvent.preventDefault();
  elBody.classList.remove(dragClass);
  [...dropEvent.dataTransfer.items].forEach((item, i) => {
    if (item.kind === "file") {
      const file = item.getAsFile();
      fReader.readAsArrayBuffer(file, 'utf-8');
    }
  });
});

function processFile(arrayBuffer){
    const byteLength = 4;

    const b1 = new Int32Array(arrayBuffer.slice(0, byteLength))[0]
    console.log(b1)

    // for (let startIdx = 0; startIdx < arrayBuffer.byteLength; startIdx += byteLength) {
    //     const byte = new Int32Array(arrayBuffer.slice(startIdx, startIdx + byteLength))[0]
    //     console.log(byte)
    // }
}

解决方案步骤

1. 提取并整理文件结构信息

先把Python代码注释里的文件结构拆解成字段列表,明确每个字段的:

  • 偏移位置
  • 字节长度
  • 数据类型(Int32/Uint16等)
  • 字节序(小端/大端)
    比如整理成这样:
  • 偏移0-3:魔数(4字节,小端Int32)
  • 偏移4-5:文件版本(2字节,大端Uint16)
  • 偏移6-9:数据块长度(4字节,小端Uint32)
  • 偏移10开始:数据块内容(长度为上一个字段的值)

2. 用DataView替代TypedArray处理二进制

你当前用的Int32Array会自动使用系统字节序,而二进制文件通常有固定的字节序要求,DataView可以精确控制字节序,是解析自定义二进制格式的更可靠工具。

3. 逐字段编写解析逻辑

基于整理的结构,修改processFile函数,逐个读取每个字段:

function processFile(arrayBuffer){
    const view = new DataView(arrayBuffer);
    let offset = 0;

    // 读取4字节小端Int32的魔数
    const magicNumber = view.getInt32(offset, true); // true=小端字节序
    offset += 4;
    console.log("魔数:", magicNumber);

    // 读取2字节大端Uint16的版本号
    const version = view.getUint16(offset, false); // false=大端字节序
    offset += 2;
    console.log("版本号:", version);

    // 读取4字节小端Uint32的数据块长度
    const dataLength = view.getUint32(offset, true);
    offset += 4;
    console.log("数据块长度:", dataLength);

    // 读取UTF-8格式的数据块内容
    const dataBuffer = arrayBuffer.slice(offset, offset + dataLength);
    const dataString = new TextDecoder("utf-8").decode(dataBuffer);
    console.log("数据内容:", dataString);

    // 后续字段按同样逻辑继续解析即可
}

4. 对齐Python代码的解析逻辑

如果Python代码用了struct.unpack(比如struct.unpack('<iH', buffer)),可以直接对应到DataView的方法:

  • <表示小端字节序,对应DataView方法的第二个参数传true
  • i对应getInt32,H对应getUint16,以此类推

5. 调试验证

用示例文件测试每个字段的解析结果,对比预期值(比如魔数是否符合文件定义、版本号是否在合理范围),如果能运行Python代码,直接对比两者的输出结果来验证正确性。


内容的提问来源于stack exchange,提问作者Chris Barr

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.12 09:13:22