1

祝各位读者和帮助者们美好的一天,我想利用我最近发现的一个 javascript 函数,它的 LZW 压缩字符串。

function lzw_encode(s) {
    var dict = {};
    var data = (s + "").split("");
    var out = [];
    var currChar;
    var phrase = data[0];
    var code = 256;
    for (var i=1; i<data.length; i++) {
        currChar=data[i];
        if (dict[phrase + currChar] != null) {
            phrase += currChar;
        }
        else {
            out.push(phrase.length > 1 ? dict[phrase] : phrase.charCodeAt(0));
            dict[phrase + currChar] = code;
            code++;
            phrase=currChar;
        }
    }
    out.push(phrase.length > 1 ? dict[phrase] : phrase.charCodeAt(0));
    for (var i=0; i<out.length; i++) {
        out[i] = String.fromCharCode(out[i]);
    }
    return out.join("");
}

这个函数实际上工作得很好,我得到的唯一问题是我想通过 websockets 传输编码的字符串,而不需要额外的编码(例如 base64),但这并不是每次都有效。有时压缩的字符串包含无法通过 websockets 传输的字符,它会引发一个 javascript 错误,表明该字符串具有非法字符。所以我的想法是在编码过程中只使用可接受的字符,比如应该用于压缩的字符“白名单”。我从代码中了解到的是它采用了某个数字的 charCode,所以我虽然可以创建自己的 charCodeSet,但我真的不知道如何实现它以及它是否可以工作。

  • Q1:我该怎么做才能让我的 lzw 编码只使用我定义的字符串的字符?
  • Q2:我还能如何“http/s”传输这些 websocket 不想传输的中文、阿拉伯文和控制字符?

顺便说一句,这是 Chrome 抛出的错误:

Websocket message contains invalid character(s).
Uncaught Error: SYNTAX_ERR: DOM Exception 12 

更新1:虽然如果你也看到解码功能它可能会有所帮助

function lzw_decode(s) {
    var dict = {};
    var data = (s + "").split("");
    var currChar = data[0];
    var oldPhrase = currChar;
    var out = [currChar];
    var code = 256;
    var phrase;
    for (var i=1; i<data.length; i++) {
        var currCode = data[i].charCodeAt(0);
        if (currCode < 256) {
            phrase = data[i];
        }
        else {
           phrase = dict[currCode] ? dict[currCode] : (oldPhrase + currChar);
        }
        out.push(phrase);
        currChar = phrase.charAt(0);
        dict[code] = oldPhrase + currChar;
        code++;
        oldPhrase = phrase;
    }
    return out.join("");
}

在这里我也必须实现我的自定义字符集,我猜?..

4

1 回答 1

1

确定可以发送和不能发送的字节。(希望来自可靠的文档来源,而不是测试,但通过测试验证。)

设计一个转义码,您使用其中一个有效字符作为转义字符,而下一个字符(也是有效字符之一)对您无法发送的字节进行编码。

将其应用于压缩机的输出。最好将压缩工作留给压缩器,而不是试图用编码来负担它。您应该将编码作为一个单独的步骤。

不要使用LZW。与现代方法( zliblz4lzma等)相比,它无效且过时

于 2013-03-14T21:46:23.423 回答