zlib Nodejs 标头检查不正确,为什么?

问题描述 投票:0回答:1

我有一个无法理解的问题。

我正在尝试在 javascript (nodejs) 中使用 zlib 解压缩 Base64 字符串

const {inflateSync} = require('zlib')
const base64Data = "7ZW9DoIwEIDf5WYwvesfdnfWRAbFOBDDQIxgoE6Edxd9AXuTDLdc0uQbrl/zpRMc+rGNbd9BuExQto9mjPXjCQFIkc7VNkdXIgVrgvYbhVhYchVksOvi0DYjhAnwM46xjq/lCPuuHOrbfUFOEFQG5++sljlnQOmoSUdRMVjGtsjZwTHYgmGMcTdi6CXNYBkeyKezmvEWhuHBMPa1Np11DGee4aFI9jDP2e9KtcZCGYlUIpVIVxup1ei9lq9UKpVK11upt+iNIqlUKpVK/1PpdX4D"

try{
    const decoded_data = inflateSync(Buffer.from(base64Data, 'base64'));
    console.log(decoded_data.toString());
}catch (error) {
    console.error(error)
}

但是它给了我一个错误

Error: incorrect header check
    at Zlib.zlibOnError [as onerror] (node:zlib:189:17)
    at processChunkSync (node:zlib:457:12)
    at zlibBufferSync (node:zlib:178:12)
    at syncBufferWrapper (node:zlib:792:14)
    at Object.<anonymous> (/Users/docs/index.js:15:26)
    at Module._compile (node:internal/modules/cjs/loader:1159:14)
    at Module._extensions..js (node:internal/modules/cjs/loader:1213:10)
    at Module.load (node:internal/modules/cjs/loader:1037:32)
    at Module._load (node:internal/modules/cjs/loader:878:12) {
  errno: -3,
  code: 'Z_DATA_ERROR'
}

Process finished with exit code 0

我还需要添加一些东西吗?

我做错了什么吗?

我的理解是窗口大小位是错误的,但是javascript不允许像python那样允许负窗口

谢谢大家

在Python中,我有以下脚本来从base64解压缩一些数据,并且效果很好

import base64
import zlib

data="7ZW9DoIwEIDf5WYwvesfdnfWRAbFOBDDQIxgoE6Edxd9AXuTDLdc0uQbrl/zpRMc+rGNbd9BuExQto9mjPXjCQFIkc7VNkdXIgVrgvYbhVhYchVksOvi0DYjhAnwM46xjq/lCPuuHOrbfUFOEFQG5++sljlnQOmoSUdRMVjGtsjZwTHYgmGMcTdi6CXNYBkeyKezmvEWhuHBMPa1Np11DGee4aFI9jDP2e9KtcZCGYlUIpVIVxup1ei9lq9UKpVK11upt+iNIqlUKpVK/1PpdX4D"

decoded_data =  zlib.decompress(base64.b64decode(data), -zlib.MAX_WBITS)
print(decoded_data)

结果是这样的

{
  "Position":[
    {
      "Timestamp":"2023-09-16T12:54:37.0118526Z",
      "Entries":{
        "1":{"Status":"OnTrack","X":0,"Y":0,"Z":0},
        "2":{"Status":"OnTrack","X":0,"Y":0,"Z":0}
      }
    }
    ....
  ]
}
javascript python node.js base64 zlib
1个回答
0
投票

使用

inflateRawSync
而不是
inflateSync
。然后就可以了。

const {inflateRawSync} = require('zlib')
const base64Data = "7ZW9DoIwEIDf5WYwvesfdnfWRAbFOBDDQIxgoE6Edxd9AXuTDLdc0uQbrl/zpRMc+rGNbd9BuExQto9mjPXjCQFIkc7VNkdXIgVrgvYbhVhYchVksOvi0DYjhAnwM46xjq/lCPuuHOrbfUFOEFQG5++sljlnQOmoSUdRMVjGtsjZwTHYgmGMcTdi6CXNYBkeyKezmvEWhuHBMPa1Np11DGee4aFI9jDP2e9KtcZCGYlUIpVIVxup1ei9lq9UKpVK11upt+iNIqlUKpVK/1PpdX4D"

try{
    const decoded_data = inflateRawSync(Buffer.from(base64Data, 'base64'));
    console.log(decoded_data.toString());
}catch (error) {
    console.error(error)
}

(顺便说一句:根据下面的描述,我认为

unzipSync
也应该可以工作,但由于某种原因,unzipSync 也会抛出
Error: incorrect header check
。)

参考资料:

来自https://nodejs.org/api/zlib.html

  • zlib.inflateRawSync(buffer[, options]): 使用
    InflateRaw
    解压一大块数据。
  • 类:zlib.InflateRaw:解压缩原始放气流。
  • zlib.unzipSync(buffer[, options]): 使用
    Unzip
    .
  • 解压一大块数据
  • 类:zlib.Unzip:通过自动检测标头来解压缩 Gzip 或 Deflate 压缩流。

来自https://docs.python.org/3/library/zlib.html

wbits 参数控制历史缓冲区的大小(或“窗口大小”),以及预期的标头和标尾格式。它与 compressobj() 的参数类似,但接受更多范围的值:

  • +8 到 +15:窗口大小的以 2 为底的对数。输入必须包含 zlib 标头和尾部。
  • 0:自动从 zlib 头确定窗口大小。仅自 zlib 1.2.3.5 起支持。
  • −8 至 −15:使用 wbits 的绝对值作为窗口大小的对数。 输入必须是没有标头或标尾的原始流。
  • +24 到 +31 = 16 + (8 到 15):使用该值的低 4 位作为窗口大小的对数。输入必须包含 gzip 标头和尾部。
  • +40 到 +47 = 32 +(8 到 15):使用该值的低 4 位作为窗口大小对数,并自动接受 zlib 或 gzip 格式。
© www.soinside.com 2019 - 2024. All rights reserved.