使用brotli压缩和解压utf8字符串
Compress and decompress utf8 string with brotli
我正在尝试编写压缩和解压缩 JSON 字符串,但解压缩总是失败:
Error: Decompression failed
at BrotliDecoder.zlibOnError [as onerror] (zlib.js:170:17) {
errno: -6,
code: 'ERR_CL_SPACE'
}
我无法发送压缩器返回的缓冲区,因为我需要通过 HTTP 响应发送压缩后的字符串才能将其取回。
此外,如果我使用 base64
作为格式,一切都有效,但字符串输出比简单的 JSON.stringify
大,所以我会避免它。
我的代码:
const zlib = require('zlib')
function compress (json) {
zlib.brotliCompress(JSON.stringify(json), {
params: {
[zlib.constants.BROTLI_PARAM_MODE]: zlib.constants.BROTLI_MODE_TEXT
}
}, (err, data) => {
console.log(err)
console.log(data.toString('utf8'))
console.log('-------------------------------')
decompress(Buffer.from(data.toString('utf8'), 'utf8'))
})
}
function decompress (str) {
zlib.brotliDecompress(str, (err, data) => {
console.log(err)
console.log(data)
})
}
const obj = {
wt: '5de52e98aa54253147060a01',
ex: ['b9ac4a6b-2e72-4bf3-abd5-debf2ece4ba4']
}
compress(obj)
是否有任何参数可以从压缩中获得有效的 utf8 字符串输出?
我认为在任何情况下您都必须使用 base64 通过网络发送数据,这将导致大约 37% 的大小损失。这实际上可能比发送 UTF8 更有效,因为许多字节需要多字节编码(发送二进制数据时)。
无论如何,当我们将压缩数据作为 base64 传递时,压缩和解压缩都会起作用。
我认为它不能与 UTF8 一起工作的原因是将缓冲区转换为 utf8 并再次转换回来并不总是可逆的,也就是说你不一定会得到相同的结果(尝试将随机数据编码为 utf8 和又回来了!)
const zlib = require('zlib')
// Encode the buffer in base 64. UCS2 will work, but UTF8 will not.
const encoding = "base64";
function compress (json) {
zlib.brotliCompress(JSON.stringify(json), {
params: {
[zlib.constants.BROTLI_PARAM_MODE]: zlib.constants.BROTLI_MODE_TEXT
}
}, (err, data) => {
if (err) {
console.error("brotliCompress: An error occurred:", err);
} else {
console.log("Compressed data:", data.toString("base64"));
console.log('-------------------------------')
decompress(data.toString(encoding), encoding);
}
})
}
function decompress (encodedData, encoding) {
const compressedData = Buffer.from(encodedData, encoding);
zlib.brotliDecompress(compressedData, (err, data) => {
if (err) {
console.error("brotliDecompress: An error occurred:", err);
} else {
console.log("Decompressed data:", data.toString("utf8"));
}
});
}
const obj = {
wt: '5de52e98aa54253147060a01',
ex: ['b9ac4a6b-2e72-4bf3-abd5-debf2ece4ba4']
}
compress(obj);
并显示 Buffer.from(data.toString("utf8"), "utf8") 并不总是可逆的:
const crypto = require("crypto");
const data = crypto.randomBytes(100);
console.log("Bytes (base64):", data .toString("base64"));
const encoding = "utf8";
const dataUtf8 = data.toString(encoding);
const decoded = Buffer.from(dataUtf8, encoding);
console.log("Bytes (base64 decoded):", decoded.toString("base64"));
您将在不同的缓冲区中看到往返结果。
我正在尝试编写压缩和解压缩 JSON 字符串,但解压缩总是失败:
Error: Decompression failed
at BrotliDecoder.zlibOnError [as onerror] (zlib.js:170:17) {
errno: -6,
code: 'ERR_CL_SPACE'
}
我无法发送压缩器返回的缓冲区,因为我需要通过 HTTP 响应发送压缩后的字符串才能将其取回。
此外,如果我使用 base64
作为格式,一切都有效,但字符串输出比简单的 JSON.stringify
大,所以我会避免它。
我的代码:
const zlib = require('zlib')
function compress (json) {
zlib.brotliCompress(JSON.stringify(json), {
params: {
[zlib.constants.BROTLI_PARAM_MODE]: zlib.constants.BROTLI_MODE_TEXT
}
}, (err, data) => {
console.log(err)
console.log(data.toString('utf8'))
console.log('-------------------------------')
decompress(Buffer.from(data.toString('utf8'), 'utf8'))
})
}
function decompress (str) {
zlib.brotliDecompress(str, (err, data) => {
console.log(err)
console.log(data)
})
}
const obj = {
wt: '5de52e98aa54253147060a01',
ex: ['b9ac4a6b-2e72-4bf3-abd5-debf2ece4ba4']
}
compress(obj)
是否有任何参数可以从压缩中获得有效的 utf8 字符串输出?
我认为在任何情况下您都必须使用 base64 通过网络发送数据,这将导致大约 37% 的大小损失。这实际上可能比发送 UTF8 更有效,因为许多字节需要多字节编码(发送二进制数据时)。
无论如何,当我们将压缩数据作为 base64 传递时,压缩和解压缩都会起作用。
我认为它不能与 UTF8 一起工作的原因是将缓冲区转换为 utf8 并再次转换回来并不总是可逆的,也就是说你不一定会得到相同的结果(尝试将随机数据编码为 utf8 和又回来了!)
const zlib = require('zlib')
// Encode the buffer in base 64. UCS2 will work, but UTF8 will not.
const encoding = "base64";
function compress (json) {
zlib.brotliCompress(JSON.stringify(json), {
params: {
[zlib.constants.BROTLI_PARAM_MODE]: zlib.constants.BROTLI_MODE_TEXT
}
}, (err, data) => {
if (err) {
console.error("brotliCompress: An error occurred:", err);
} else {
console.log("Compressed data:", data.toString("base64"));
console.log('-------------------------------')
decompress(data.toString(encoding), encoding);
}
})
}
function decompress (encodedData, encoding) {
const compressedData = Buffer.from(encodedData, encoding);
zlib.brotliDecompress(compressedData, (err, data) => {
if (err) {
console.error("brotliDecompress: An error occurred:", err);
} else {
console.log("Decompressed data:", data.toString("utf8"));
}
});
}
const obj = {
wt: '5de52e98aa54253147060a01',
ex: ['b9ac4a6b-2e72-4bf3-abd5-debf2ece4ba4']
}
compress(obj);
并显示 Buffer.from(data.toString("utf8"), "utf8") 并不总是可逆的:
const crypto = require("crypto");
const data = crypto.randomBytes(100);
console.log("Bytes (base64):", data .toString("base64"));
const encoding = "utf8";
const dataUtf8 = data.toString(encoding);
const decoded = Buffer.from(dataUtf8, encoding);
console.log("Bytes (base64 decoded):", decoded.toString("base64"));
您将在不同的缓冲区中看到往返结果。