解压缩后如何取回原始字符串 - Zlib

How to get back the original string after decompressing - Zlib

本文关键字:字符串 Zlib 原始 何取回 解压缩      更新时间:2023-09-26

我正在尝试使用 Zlib 压缩和解压缩字符串。这是我用来压缩和解压缩的JS文件。

压缩代码:

compress_string = function () {
   var string = document.getElementById("input_value").value;
   var deflate = new Zlib.Deflate(string);
   var compressed = deflate.compress();
   var b64encoded = btoa(String.fromCharCode.apply(null, compressed));
   var elem = document.getElementById("input_value");
   elem.value = b64encoded;
   var elemLabel = document.getElementById("zlsize");
   elemLabel.value = ("Size of sample is: " + string.length) + " " + ("Compressed Value: " + b64encoded + " Size: " + b64encoded.length);
}

压缩后,我将压缩值设置回input_value文本字段。

解压代码:

decompress_string = function () {
   var string = document.getElementById("input_value").value;
   var compressData = new Uint8Array(atob(string).split("").map(function(c) { return c.charCodeAt(0); }))
   var inflate = new Zlib.Inflate(compressData);
   var plain = inflate.decompress();
   var elem = document.getElementById("input_value");
   elem.value = btoa(plain);
   var elemLabel = document.getElementById("zlsize");
   elemLabel.value = ("Size of compressed string is: " + string.length) + " " + ("Decompressed Value: " + plain + " Size: " + plain.length);
}

我正在尝试压缩以下示例字符串:

<xml><username>myusername</username><password>mypassword</password></xml>

样品大小为:73

压缩值:eJxNibEJAAAMg/7/OjoEdCjGAoAnmqg6fF8T7QMfCxxR

尺寸: 44

尝试解压缩上述压缩字符串时,我得到一个Uint8Array的对象,如下所示:

压缩字符串的大小为:44

解压值:[object Uint8Array]

尺寸: 70

尝试使用 btoa() 将对象Uint8Array转换为字符串时,输出如下所示:

W29iamVjdCBVaW50OEFycmF5XQ==

问:如何获取原始字符串?

您的问题是文本编码。

Uint8Array 是某物的二进制表示,字符串可以用多种格式编写。您需要坚持一个,并使用它进行转换。

在这个例子中,我选择了 UTF-8,使用了这个库

function compress(input){
    var binaryconverter = new TextEncoder('utf-8');
    var binary = binaryconverter.encode(input);
    var deflate = new Zlib.Deflate(binary);
    var compressed = deflate.compress();
    return btoa(String.fromCharCode.apply(null, compressed));
}
function decompress(b64encoded){
    var compressed = new Uint8Array(atob(b64encoded).split("").map(function(c){return c.charCodeAt(0);}));
    var inflate = new Zlib.Inflate(compressed);
    var binary = inflate.decompress();
    var binaryconverter = new TextDecoder('utf-8');
    return binaryconverter.decode(binary);
}
var input = '<xml><username>myusername</username><password>mypassword</password></xml>';
var b64encoded = compress(input);
var output = decompress(b64encoded);
alert(output);

因此,在编码时,我首先将字符串转换为 UTF-8 格式文本的二进制表示形式,然后使用 ZLib 进行压缩,然后再次将其转换为 base64 字符串以便于传输。

要解压缩,你做相反的事情:首先解码 base64 字符串,然后 ZLib 膨胀,最后我们再次使用 UTF-8 将二进制转换为字符串

文档 zlib.js 似乎建议plain(输入)类型为 Array.<number> or Uint8Array

    // plain = Array.<number> or Uint8Array
    var deflate = new Zlib.Deflate(plain);
    var compressed = deflate.compress();

在 OP 中,var string似乎是类型 string,参见

   var string = document.getElementById("input_value").value;
   var deflate = new Zlib.Deflate(string);

要从压缩的 text 中检索 值,base64格式化的字符串,下面; 首先,将var string映射到.charCodeAt() number,返回表示文本字符的number数组;二、推.charCodeAt()数字到映射数组;第三,调用window.btoa(encodeURIComponent(escape(compressed[i]))) charCodeAt()值数组内的每个项目,推送到同一个map数组;第四,在循环中解码base64encoded字符串for,在解压的Uint8Array上调用String.fromCharCode(plain[i]),返回原始输入string

尝试

var elem = document.getElementById("input_value")
    , elemLabel = document.getElementById("zlsize")
    , compress = document.getElementById("compress")
    , decompress = document.getElementById("decompress")
    , b64map = []
    , _b64encoded
    , b64encoded
    , _string
    , string
    , _plain
    , compressData;
    function compress_string () {
        string = elem.value;
        _string = [].slice.call(string).map(function (value, key) {
            return value.charCodeAt(0)
        });
        var deflate = new Zlib.Deflate(_string);
        var compressed = deflate.compress();
        for (var i = 0; i < compressed.length; i++) {
            b64map.push([compressed[i]
                , window.btoa(encodeURIComponent(escape(compressed[i])))])
        };
        _b64encoded = b64map.map(function (value, key) {
            return value[1]
        });
        b64encoded = _b64encoded.join("");
        elem.value = b64encoded;
        elemLabel.innerText = ("Size of sample is: " 
                              + string.length) + " " + ("Compressed Value: " 
                              + b64encoded + " Size: " + b64encoded.length)
    };
    function decompress_string () {
        string = elem.value;
        elem.value = "";
        compressData = _b64encoded.map(function (value, key) {                      
            return new RegExp(value).test(string) ? b64map[key][0] : null
        });
        compressData = new Uint8Array(compressData);
        var inflate = new Zlib.Inflate(compressData);
        var plain = inflate.decompress();
        b64map = b64encoded = [];
        _plain = "";
        for (var i = 0; i < plain.length; i++) {
            _plain += String.fromCharCode(plain[i])
        };
        elem.value = _plain;
        elemLabel.innerText = ("Size of compressed string is: " 
                              + elem.value.length) + " " 
                              + ("Decompressed Value: " + _plain + " Size: " 
                              + _plain.length);
    };
    compress.addEventListener("click", compress_string);
    decompress.addEventListener("click", decompress_string);

JSFIDDLE http://jsfiddle.net/guest271314/ov6nwLak/

$.getScript("https://raw.githubusercontent.com/imaya/zlib.js/master/bin/zlib.min.js")
var elem = document.getElementById("input_value")
    , elemLabel = document.getElementById("zlsize")
    , compress = document.getElementById("compress")
    , decompress = document.getElementById("decompress")
    , b64map = []
    , _b64encoded
    , b64encoded
    , _string
    , string
    , _plain
    , compressData;
    elem.value = "<xml><username>myusername</username><password>mypassword</password></xml>";
    function compress_string () {
        string = elem.value;
        _string = [].slice.call(string).map(function (value, key) {
            return value.charCodeAt(0)
        });
        var deflate = new Zlib.Deflate(_string);
        var compressed = deflate.compress();
        for (var i = 0; i < compressed.length; i++) {
            b64map.push([compressed[i]
                , window.btoa(encodeURIComponent(escape(compressed[i])))])
        };
        _b64encoded = b64map.map(function (value, key) {
            return value[1]
        });
        b64encoded = _b64encoded.join("");
        elem.value = b64encoded;
        elemLabel.innerText = ("Size of sample is: " 
                              + string.length) + " " + ("Compressed Value: " 
                              + b64encoded + " Size: " + b64encoded.length)
    };
    
    function decompress_string () {
        string = elem.value;
        elem.value = "";
        compressData = _b64encoded.map(function (value, key) {                      
            return new RegExp(value).test(string) ? b64map[key][0] : null
        });
        
        compressData = new Uint8Array(compressData);
        var inflate = new Zlib.Inflate(compressData);
    
        var plain = inflate.decompress();
        b64map = b64encoded = [];
        _plain = "";
        for (var i = 0; i < plain.length; i++) {
            _plain += String.fromCharCode(plain[i])
        };
        elem.value = _plain;
        elemLabel.innerText = ("Size of compressed string is: " 
                              + elem.value.length) + " " 
                              + ("Decompressed Value: " + _plain + " Size: " +         
                              _plain.length);
    };
    
    compress.addEventListener("click", compress_string);
    decompress.addEventListener("click", decompress_string);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>

<input type="text" id="input_value" />
<button id="compress">compress</button>
<button id="decompress">decompress</button>
<br />
<label id="zlsize"></label>