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

基于JavaScript的音频文件隐写文本提取问题求助

解决音频文件中提取隐藏明文的问题

我看到你遇到的问题了——你已经拿到了音频的Blob对象,但因为Promise处理不当和后续二进制解析的逻辑没理清卡住了。咱们一步步来解决:

首先,修正Blob的获取逻辑

你代码里的response.blob()返回的是一个Promise对象,不是直接的Blob实例。这就是为什么你用FileReader时会报错——你传递的是Promise,而非真正的Blob。你需要等待这个Promise完成,才能拿到可用的Blob:

方式1:用链式.then()处理

function playMusic() { 
  if (!isPaused) { 
    const blobUrl = URL.createObjectURL(songs[currentSong]); 
    fetch(blobUrl)
      .then(response => response.blob()) // 等待Blob解析完成
      .then(fileAsBlob => {
        console.log("拿到真正的Blob了:", fileAsBlob);
        // 在这里添加后续的文本提取逻辑
      })
      .catch(err => console.error("请求音频出错:", err));
  }
}

方式2:用async/await简化代码(更易读)

async function playMusic() { 
  if (!isPaused) { 
    try {
      const blobUrl = URL.createObjectURL(songs[currentSong]); 
      const response = await fetch(blobUrl);
      const fileAsBlob = await response.blob(); // 等待Promise完成,拿到Blob
      console.log("拿到真正的Blob了:", fileAsBlob);
      // 后续处理逻辑写在这里
    } catch (err) {
      console.error("处理音频时出错:", err);
    }
  }
}

然后,从Blob中提取隐藏明文

根据你说的“文本直接藏在二进制代码中”,分两种场景处理:

场景1:隐藏文本是UTF-8编码的连续字符串

如果文本是直接嵌入在二进制中的可读字符串(比如在音频文件末尾或某个固定位置),可以直接用Blob的text()方法读取全部内容,再搜索目标文本:

async function playMusic() { 
  if (!isPaused) { 
    try {
      const blobUrl = URL.createObjectURL(songs[currentSong]); 
      const response = await fetch(blobUrl);
      const fileAsBlob = await response.blob();
      const fullContent = await fileAsBlob.text(); // 把Blob转成文本字符串
      
      // 示例:搜索以"SECRET:"开头的内容
      const hiddenTextMatch = fullContent.match(/SECRET: (.*)/);
      if (hiddenTextMatch) {
        console.log("找到隐藏文本:", hiddenTextMatch[1]);
      } else {
        console.log("未找到目标隐藏文本");
      }

      // 记得释放Blob URL,避免内存泄漏
      URL.revokeObjectURL(blobUrl);
    } catch (err) {
      console.error("出错了:", err);
    }
  }
}

场景2:文本藏在二进制字节的特定位置

如果文本是藏在特定字节序列之后(比如自定义的标记开头/结尾),需要读取二进制数组来精准定位:

async function playMusic() { 
  if (!isPaused) { 
    try {
      const blobUrl = URL.createObjectURL(songs[currentSong]); 
      const response = await fetch(blobUrl);
      const arrayBuffer = await response.arrayBuffer(); // 直接读取二进制数组,比转Blob更高效
      const uint8Array = new Uint8Array(arrayBuffer);
      
      // 示例:查找以"START_HIDDEN"开头、"END_HIDDEN"结尾的内容
      const startMarker = new TextEncoder().encode("START_HIDDEN");
      const endMarker = new TextEncoder().encode("END_HIDDEN");
      
      // 定位起始标记的位置
      let startIndex = -1;
      for (let i = 0; i <= uint8Array.length - startMarker.length; i++) {
        let isMatch = true;
        for (let j = 0; j < startMarker.length; j++) {
          if (uint8Array[i + j] !== startMarker[j]) {
            isMatch = false;
            break;
          }
        }
        if (isMatch) {
          startIndex = i + startMarker.length;
          break;
        }
      }
      
      if (startIndex !== -1) {
        // 定位结束标记的位置
        let endIndex = -1;
        for (let i = startIndex; i <= uint8Array.length - endMarker.length; i++) {
          let isMatch = true;
          for (let j = 0; j < endMarker.length; j++) {
            if (uint8Array[i + j] !== endMarker[j]) {
              isMatch = false;
              break;
            }
          }
          if (isMatch) {
            endIndex = i;
            break;
          }
        }
        
        // 提取并转换为文本
        if (endIndex !== -1) {
          const hiddenBytes = uint8Array.slice(startIndex, endIndex);
          const hiddenText = new TextDecoder().decode(hiddenBytes);
          console.log("找到隐藏文本:", hiddenText);
        }
      }

      URL.revokeObjectURL(blobUrl);
    } catch (err) {
      console.error("出错了:", err);
    }
  }
}

补充说明

你之前尝试手动创建Blob实例报错完全没必要——response.blob()已经返回了正确类型的Blob(从你的控制台输出能看到type是audio/mpeg),直接使用这个实例即可,不需要自己构造。

内容的提问来源于stack exchange,提问作者Vineet Mishra

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.09 13:52:51