我有一个无法理解的问题。
我正在尝试在 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}
}
}
....
]
}
使用
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 格式。